LCOV - code coverage report
Current view: top level - libpskc - output.c (source / functions) Hit Total Coverage
Test: OATH Toolkit Lines: 196 210 93.3 %
Date: 2021-08-21 19:02:00 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * output.c - Pretty print PSKC data.
       3             :  * Copyright (C) 2012-2021 Simon Josefsson
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or
       6             :  * modify it under the terms of the GNU Lesser General Public License
       7             :  * as published by the Free Software Foundation; either version 2.1 of
       8             :  * the License, or (at your option) any later version.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful, but
      11             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :  * Lesser General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public
      16             :  * License along with this library; if not, write to the Free Software
      17             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      18             :  * 02110-1301 USA
      19             :  *
      20             :  */
      21             : 
      22             : #include <config.h>
      23             : 
      24             : #include <pskc/pskc.h>
      25             : 
      26             : #include "minmax.h"
      27             : 
      28             : #define INTERNAL_NEED_PSKC_STRUCT
      29             : #include "internal.h"
      30             : #include <stdlib.h>               /* malloc */
      31             : #include <string.h>               /* memmove */
      32             : #include <inttypes.h>             /* PRId64 */
      33             : #include <libxml/parser.h>        /* xmlInitParser */
      34             : 
      35             : struct buffer
      36             : {
      37             :   char *mem;                    /* NULL if malloc has failed */
      38             :   size_t memlen;                /* length of allocated buffer */
      39             :   size_t dlen;                  /* length of data in buffer */
      40             : };
      41             : 
      42             : #define CHUNK 1024
      43             : 
      44             : static void
      45           4 : buffer_init (struct buffer *buf)
      46             : {
      47           4 :   buf->memlen = CHUNK;
      48           4 :   buf->mem = malloc (buf->memlen);
      49           4 :   if (buf->mem)
      50           4 :     buf->mem[0] = '\0';
      51           4 :   buf->dlen = 0;
      52           4 : }
      53             : 
      54             : static void
      55           4 : buffer_getstr (struct buffer *buf, char **str, size_t *dlen)
      56             : {
      57           4 :   *str = buf->mem;
      58           4 :   *dlen = buf->dlen;
      59           4 : }
      60             : 
      61             : static void
      62         152 : buffer_add (struct buffer *buf, size_t len, const void *data)
      63             : {
      64             :   size_t n;
      65             : 
      66         152 :   if (len == 0 || buf->mem == NULL)
      67           0 :     return;
      68             : 
      69         152 :   n = buf->dlen + len;
      70         152 :   if (buf->memlen > n)
      71             :     {
      72         149 :       memmove (&buf->mem[buf->dlen], data, len);
      73         149 :       buf->dlen = n;
      74         149 :       buf->mem[buf->dlen] = '\0';
      75             :     }
      76             :   else
      77             :     {
      78           3 :       size_t newlen = buf->memlen + MAX (len, CHUNK);
      79             :       char *tmp;
      80             : 
      81           3 :       tmp = realloc (buf->mem, newlen);
      82           3 :       if (tmp == NULL)
      83             :         {
      84           0 :           free (buf->mem);
      85           0 :           buf->mem = NULL;
      86           0 :           return;
      87             :         }
      88           3 :       buf->mem = tmp;
      89           3 :       buf->memlen = newlen;
      90             : 
      91           3 :       memmove (&buf->mem[buf->dlen], data, len);
      92             : 
      93           3 :       buf->dlen = n;
      94           3 :       buf->mem[buf->dlen] = '\0';
      95             :     }
      96             : }
      97             : 
      98             : static void
      99         152 : buffer_addz (struct buffer *buf, const char *str)
     100             : {
     101         152 :   buffer_add (buf, strlen (str), str);
     102         152 : }
     103             : 
     104             : static void
     105             : buffer_addf (struct buffer *buf, const char *fmt, ...)
     106             : __attribute__((format (printf, 2, 3)));
     107             : 
     108             : static void
     109         140 : buffer_addf (struct buffer *buf, const char *fmt, ...)
     110             : {
     111             :   va_list args;
     112             :   int len;
     113             :   char *str;
     114             : 
     115         140 :   va_start (args, fmt);
     116         140 :   len = vasprintf (&str, fmt, args);
     117         140 :   va_end (args);
     118             : 
     119         140 :   if (len < 0 || !str)
     120             :     {
     121           0 :       free (buf->mem);
     122           0 :       buf->mem = NULL;
     123           0 :       return;
     124             :     }
     125             : 
     126         140 :   buffer_addz (buf, str);
     127             : 
     128         140 :   free (str);
     129             : }
     130             : 
     131             : static void
     132           4 : print_keypackage (struct buffer *buf, pskc_key_t * kp)
     133             : {
     134           4 :   const char *device_manufacturer = pskc_get_device_manufacturer (kp);
     135           4 :   const char *device_serialno = pskc_get_device_serialno (kp);
     136           4 :   const char *device_model = pskc_get_device_model (kp);
     137           4 :   const char *device_issueno = pskc_get_device_issueno (kp);
     138           4 :   const char *device_devicebinding = pskc_get_device_devicebinding (kp);
     139           4 :   const struct tm *device_startdate = pskc_get_device_startdate (kp);
     140           4 :   const struct tm *device_expirydate = pskc_get_device_expirydate (kp);
     141           4 :   const char *device_userid = pskc_get_device_userid (kp);
     142           4 :   const char *cryptomodule_id = pskc_get_cryptomodule_id (kp);
     143           4 :   const char *key_id = pskc_get_key_id (kp);
     144           4 :   const char *key_friendlyname = pskc_get_key_friendlyname (kp);
     145           4 :   const char *key_issuer = pskc_get_key_issuer (kp);
     146           4 :   const char *key_profileid = pskc_get_key_profileid (kp);
     147           4 :   const char *key_reference = pskc_get_key_reference (kp);
     148           4 :   const char *key_userid = pskc_get_key_userid (kp);
     149           4 :   const char *key_algorithm = pskc_get_key_algorithm (kp);
     150           4 :   const char *key_b64secret = pskc_get_key_data_b64secret (kp);
     151             :   int key_counter_present;
     152           4 :   uint64_t key_counter = pskc_get_key_data_counter (kp, &key_counter_present);
     153             :   int key_time_present;
     154           4 :   uint32_t key_time = pskc_get_key_data_time (kp, &key_time_present);
     155             :   int key_timedrift_present;
     156           4 :   uint32_t key_timedrift = pskc_get_key_data_timedrift
     157             :     (kp, &key_timedrift_present);
     158             :   int key_timeinterval_present;
     159           4 :   uint32_t key_timeinterval = pskc_get_key_data_timeinterval
     160             :     (kp, &key_timeinterval_present);
     161           4 :   const char *key_policy_pinkeyid = pskc_get_key_policy_pinkeyid (kp);
     162             :   int key_policy_pinminlength_present;
     163           4 :   uint32_t key_policy_pinminlength = pskc_get_key_policy_pinminlength
     164             :     (kp, &key_policy_pinminlength_present);
     165             :   int key_policy_pinmaxlength_present;
     166           4 :   uint32_t key_policy_pinmaxlength = pskc_get_key_policy_pinmaxlength
     167             :     (kp, &key_policy_pinmaxlength_present);
     168             :   int key_policy_pinmaxfailedattempts_present;
     169             :   uint32_t key_policy_pinmaxfailedattempts =
     170           4 :     pskc_get_key_policy_pinmaxfailedattempts (kp,
     171             :                                               &key_policy_pinmaxfailedattempts_present);
     172             :   int key_policy_pinusagemode_present;
     173             :   pskc_pinusagemode key_policy_pinusagemode =
     174           4 :     pskc_get_key_policy_pinusagemode (kp, &key_policy_pinusagemode_present);
     175             :   int key_policy_pinencoding_present;
     176             :   pskc_valueformat key_policy_pinencoding =
     177           4 :     pskc_get_key_policy_pinencoding (kp, &key_policy_pinencoding_present);
     178             :   int key_policy_keyusages_present;
     179             :   int key_policy_keyusages =
     180           4 :     pskc_get_key_policy_keyusages (kp, &key_policy_keyusages_present);
     181           4 :   const char *key_algparm_suite = pskc_get_key_algparm_suite (kp);
     182             :   int key_algparm_chall_encoding_present;
     183             :   pskc_valueformat key_algparm_chall_encoding =
     184           4 :     pskc_get_key_algparm_chall_encoding (kp,
     185             :                                          &key_algparm_chall_encoding_present);
     186             :   int key_algparm_chall_min_present;
     187             :   uint32_t key_algparm_chall_min =
     188           4 :     pskc_get_key_algparm_chall_min (kp, &key_algparm_chall_min_present);
     189             :   int key_algparm_chall_max_present;
     190             :   uint32_t key_algparm_chall_max =
     191           4 :     pskc_get_key_algparm_chall_max (kp, &key_algparm_chall_max_present);
     192             :   int key_algparm_resp_encoding_present;
     193             :   pskc_valueformat key_algparm_resp_encoding =
     194           4 :     pskc_get_key_algparm_resp_encoding (kp,
     195             :                                         &key_algparm_resp_encoding_present);
     196             :   int key_algparm_resp_length_present;
     197             :   uint32_t key_algparm_resp_length =
     198           4 :     pskc_get_key_algparm_resp_length (kp, &key_algparm_resp_length_present);
     199           4 :   const struct tm *key_policy_startdate = pskc_get_key_policy_startdate (kp);
     200             :   const struct tm *key_policy_expirydate =
     201           4 :     pskc_get_key_policy_expirydate (kp);
     202             : 
     203           4 :   buffer_addz (buf, "\t\tDeviceInfo:\n");
     204           4 :   if (device_manufacturer)
     205           4 :     buffer_addf (buf, "\t\t\tManufacturer: %s\n", device_manufacturer);
     206           4 :   if (device_serialno)
     207           4 :     buffer_addf (buf, "\t\t\tSerialNo: %s\n", device_serialno);
     208           4 :   if (device_model)
     209           3 :     buffer_addf (buf, "\t\t\tModel: %s\n", device_model);
     210           4 :   if (device_issueno)
     211           3 :     buffer_addf (buf, "\t\t\tIssueNo: %s\n", device_issueno);
     212           4 :   if (device_devicebinding)
     213           3 :     buffer_addf (buf, "\t\t\tDeviceBinding: %s\n", device_devicebinding);
     214           4 :   if (device_startdate)
     215             :     {
     216             :       char t[100];
     217           3 :       strftime (t, sizeof (t), "%Y-%m-%d %H:%M:%S", device_startdate);
     218           3 :       buffer_addf (buf, "\t\t\tDevice StartDate: %s\n", t);
     219             :     }
     220           4 :   if (device_expirydate)
     221             :     {
     222             :       char t[100];
     223           3 :       strftime (t, sizeof (t), "%Y-%m-%d %H:%M:%S", device_expirydate);
     224           3 :       buffer_addf (buf, "\t\t\tDevice ExpiryDate: %s\n", t);
     225             :     }
     226           4 :   if (device_userid)
     227           3 :     buffer_addf (buf, "\t\t\tUserId: %s\n", device_userid);
     228             : 
     229           4 :   if (cryptomodule_id)
     230           3 :     buffer_addf (buf, "\t\tCryptoModuleInfo Id: %s\n", cryptomodule_id);
     231             : 
     232           4 :   buffer_addz (buf, "\t\tKey:\n");
     233           4 :   if (key_id)
     234           4 :     buffer_addf (buf, "\t\t\tId: %s\n", key_id);
     235           4 :   if (key_friendlyname)
     236           3 :     buffer_addf (buf, "\t\t\tFriendlyName: %s\n", key_friendlyname);
     237           4 :   if (key_issuer)
     238           3 :     buffer_addf (buf, "\t\t\tIssuer: %s\n", key_issuer);
     239           4 :   if (key_algorithm)
     240           4 :     buffer_addf (buf, "\t\t\tAlgorithm: %s\n", key_algorithm);
     241           4 :   if (key_userid)
     242           3 :     buffer_addf (buf, "\t\t\tKey User Id: %s\n", key_userid);
     243           4 :   if (key_profileid)
     244           3 :     buffer_addf (buf, "\t\t\tKey Profile Id: %s\n", key_profileid);
     245           4 :   if (key_reference)
     246           3 :     buffer_addf (buf, "\t\t\tKey Reference: %s\n", key_reference);
     247           4 :   if (key_b64secret)
     248           4 :     buffer_addf (buf, "\t\t\tKey Secret (base64): %s\n", key_b64secret);
     249           4 :   if (key_counter_present)
     250           4 :     buffer_addf (buf, "\t\t\tKey Counter: %" PRIu64 "\n", key_counter);
     251           4 :   if (key_time_present)
     252           3 :     buffer_addf (buf, "\t\t\tKey Time: %" PRIu32 "\n", key_time);
     253           4 :   if (key_timeinterval_present)
     254           3 :     buffer_addf (buf, "\t\t\tKey TimeInterval: %" PRIu32 "\n",
     255             :                  key_timeinterval);
     256           4 :   if (key_timedrift_present)
     257           3 :     buffer_addf (buf, "\t\t\tKey TimeDrift: %" PRIu32 "\n", key_timedrift);
     258           4 :   if (key_policy_keyusages_present)
     259             :     {
     260             :       int i;
     261           3 :       buffer_addf (buf, "\t\t\tKey Usage:");
     262          36 :       for (i = 1; i <= PSKC_KEYUSAGE_LAST; i = i << 1)
     263             :         {
     264          33 :           const char *keyusage_str = pskc_keyusage2str (i);
     265             : 
     266          33 :           if (key_policy_keyusages & i)
     267           6 :             buffer_addf (buf, " %s", keyusage_str);
     268             :         }
     269           3 :       buffer_addf (buf, "\n");
     270             :     }
     271           4 :   if (key_policy_startdate)
     272             :     {
     273             :       char t[100];
     274           3 :       strftime (t, sizeof (t), "%Y-%m-%d %H:%M:%S", key_policy_startdate);
     275           3 :       buffer_addf (buf, "\t\t\tPolicy StartDate: %s\n", t);
     276             :     }
     277           4 :   if (key_policy_expirydate)
     278             :     {
     279             :       char t[100];
     280           3 :       strftime (t, sizeof (t), "%Y-%m-%d %H:%M:%S", key_policy_expirydate);
     281           3 :       buffer_addf (buf, "\t\t\tPolicy ExpiryDate: %s\n", t);
     282             :     }
     283           4 :   if (key_policy_pinminlength_present)
     284           3 :     buffer_addf (buf, "\t\t\tPIN Policy Minimum Length: %" PRIu32 "\n",
     285             :                  key_policy_pinminlength);
     286           4 :   if (key_policy_pinmaxlength_present)
     287           3 :     buffer_addf (buf, "\t\t\tPIN Policy Maximum Length: %" PRIu32 "\n",
     288             :                  key_policy_pinmaxlength);
     289           4 :   if (key_policy_pinkeyid)
     290           3 :     buffer_addf (buf, "\t\t\tPIN Policy PIN Key Id: %s\n",
     291             :                  key_policy_pinkeyid);
     292           4 :   if (key_policy_pinencoding_present)
     293           3 :     buffer_addf (buf, "\t\t\tPIN Policy PIN Encoding: %s\n",
     294             :                  pskc_valueformat2str (key_policy_pinencoding));
     295           4 :   if (key_policy_pinusagemode_present)
     296           3 :     buffer_addf (buf, "\t\t\tPIN Policy PIN Usage Mode: %s\n",
     297             :                  pskc_pinusagemode2str (key_policy_pinusagemode));
     298           4 :   if (key_policy_pinmaxfailedattempts_present)
     299           3 :     buffer_addf (buf,
     300             :                  "\t\t\tPIN Policy PIN Max Failed Attempts: %" PRIu32 "\n",
     301             :                  key_policy_pinmaxfailedattempts);
     302           4 :   if (key_algparm_suite)
     303           3 :     buffer_addf (buf, "\t\t\tAlgorithm Parameters Suite: %s\n",
     304             :                  key_algparm_suite);
     305           4 :   if (key_algparm_chall_encoding_present)
     306           3 :     buffer_addf (buf, "\t\t\tChallenge Format Encoding: %s\n",
     307             :                  pskc_valueformat2str (key_algparm_chall_encoding));
     308           4 :   if (key_algparm_chall_min_present)
     309           3 :     buffer_addf (buf, "\t\t\tChallenge Format Min: %" PRIu32 "\n",
     310             :                  key_algparm_chall_min);
     311           4 :   if (key_algparm_chall_max_present)
     312           3 :     buffer_addf (buf, "\t\t\tChallenge Format Max: %" PRIu32 "\n",
     313             :                  key_algparm_chall_max);
     314           4 :   if (key_algparm_resp_length_present)
     315           4 :     buffer_addf (buf, "\t\t\tResponse Format Length: %" PRIu32 "\n",
     316             :                  key_algparm_resp_length);
     317           4 :   if (key_algparm_resp_encoding_present)
     318           4 :     buffer_addf (buf, "\t\t\tResponse Format Encoding: %s\n",
     319             :                  pskc_valueformat2str (key_algparm_resp_encoding));
     320           4 : }
     321             : 
     322             : static void
     323           4 : print_keycontainer (pskc_t * data, struct buffer *buf)
     324             : {
     325           4 :   const char *version = pskc_get_version (data);
     326           4 :   const char *id = pskc_get_id (data);
     327           4 :   int signed_p = pskc_get_signed_p (data);
     328             :   pskc_key_t *key;
     329             :   size_t i;
     330             : 
     331           4 :   if (version)
     332           4 :     buffer_addf (buf, "\tVersion: %s\n", version);
     333           4 :   if (id)
     334           3 :     buffer_addf (buf, "\tId: %s\n", id);
     335           4 :   buffer_addf (buf, "\tSigned: %s\n", signed_p ? "YES" : "NO");
     336             : 
     337           8 :   for (i = 0; (key = pskc_get_keypackage (data, i)); i++)
     338             :     {
     339           4 :       buffer_addf (buf, "\tKeyPackage %zu:\n", i);
     340           4 :       print_keypackage (buf, key);
     341             :     }
     342           4 : }
     343             : 
     344             : /**
     345             :  * pskc_output:
     346             :  * @container: a #pskc_t handle, from pskc_init().
     347             :  * @format: an #pskc_output_formats_t enumeration type indicating format.
     348             :  * @out: pointer to output variable holding newly allocated string.
     349             :  * @len: pointer to output variable hold length of *@out.
     350             :  *
     351             :  * Convert PSKC data to a serialized string of the indicated type.
     352             :  * This is usually used to convert the PSKC data to some human
     353             :  * readable form.
     354             :  *
     355             :  * Returns: %PSKC_OK on success, or an error code.
     356             :  */
     357             : int
     358          13 : pskc_output (pskc_t * container,
     359             :              pskc_output_formats_t format, char **out, size_t *len)
     360             : {
     361          13 :   if (format == PSKC_OUTPUT_HUMAN_COMPLETE)
     362             :     {
     363             :       struct buffer buf;
     364             : 
     365           4 :       buffer_init (&buf);
     366           4 :       buffer_addz (&buf, "Portable Symmetric Key Container (PSKC):\n");
     367             : 
     368           4 :       print_keycontainer (container, &buf);
     369             : 
     370           4 :       buffer_getstr (&buf, out, len);
     371           4 :       if (*out == NULL)
     372           0 :         return PSKC_MALLOC_ERROR;
     373             :     }
     374           9 :   else if (format == PSKC_OUTPUT_XML || format == PSKC_OUTPUT_INDENTED_XML)
     375           8 :     {
     376             :       xmlChar *mem;
     377             :       int size;
     378             : 
     379           8 :       xmlDocDumpMemory (container->xmldoc, &mem, &size);
     380             : 
     381           8 :       if (format == PSKC_OUTPUT_INDENTED_XML)
     382             :         {
     383             :           xmlDocPtr xmldoc;
     384             : 
     385           1 :           xmldoc = xmlReadMemory ((const char *) mem, size, NULL, NULL,
     386             :                                   XML_PARSE_NONET | XML_PARSE_NOBLANKS);
     387           1 :           if (xmldoc == NULL)
     388           0 :             return PSKC_XML_ERROR;
     389             : 
     390           1 :           xmlFree (mem);
     391             : 
     392           1 :           xmlDocDumpFormatMemory (xmldoc, &mem, &size, 1);
     393             : 
     394           1 :           xmlFreeDoc (xmldoc);
     395             :         }
     396             : 
     397           8 :       if (mem == NULL || size <= 0)
     398             :         {
     399           0 :           if (format == PSKC_OUTPUT_XML)
     400           0 :             _pskc_debug ("xmlDocDumpMemory failed");
     401             :           else
     402           0 :             _pskc_debug ("xmlDocDumpFormatMemory failed");
     403           0 :           return PSKC_XML_ERROR;
     404             :         }
     405             : 
     406           8 :       if (len)
     407           8 :         *len = size;
     408           8 :       if (out)
     409             :         {
     410           8 :           *out = malloc (size);
     411           8 :           if (*out == NULL)
     412           0 :             return PSKC_MALLOC_ERROR;
     413             : 
     414           8 :           memcpy (*out, mem, size);
     415             :         }
     416             : 
     417           8 :       xmlFree (mem);
     418             :     }
     419             :   else
     420           1 :     return PSKC_UNKNOWN_OUTPUT_FORMAT;
     421             : 
     422          12 :   return PSKC_OK;
     423             : }

Generated by: LCOV version 1.14