LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/extras - randomart.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 54 63 85.7 %
Date: 2020-10-30 04:50:48 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* $OpenBSD: key.c,v 1.98 2011/10/18 04:58:26 djm Exp $ */
       2             : /*
       3             :  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
       4             :  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  * 1. Redistributions of source code must retain the above copyright
      10             :  *    notice, this list of conditions and the following disclaimer.
      11             :  * 2. Redistributions in binary form must reproduce the above copyright
      12             :  *    notice, this list of conditions and the following disclaimer in the
      13             :  *    documentation and/or other materials provided with the distribution.
      14             :  *
      15             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      16             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      17             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      18             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      19             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      20             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      21             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      22             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      23             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      24             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      25             :  */
      26             : 
      27             : #include "gnutls_int.h"
      28             : #include "errors.h"
      29             : #include <randomart.h>
      30             : 
      31             : /*
      32             :  * Draw an ASCII-Art representing the fingerprint so human brain can
      33             :  * profit from its built-in pattern recognition ability.
      34             :  * This technique is called "random art" and can be found in some
      35             :  * scientific publications like this original paper:
      36             :  *
      37             :  * "Hash Visualization: a New Technique to improve Real-World Security",
      38             :  * Perrig A. and Song D., 1999, International Workshop on Cryptographic
      39             :  * Techniques and E-Commerce (CrypTEC '99)
      40             :  * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
      41             :  *
      42             :  * The subject came up in a talk by Dan Kaminsky, too.
      43             :  *
      44             :  * If you see the picture is different, the key is different.
      45             :  * If the picture looks the same, you still know nothing.
      46             :  *
      47             :  * The algorithm used here is a worm crawling over a discrete plane,
      48             :  * leaving a trace (augmenting the field) everywhere it goes.
      49             :  * Movement is taken from dgst_raw 2bit-wise.  Bumping into walls
      50             :  * makes the respective movement vector be ignored for this turn.
      51             :  * Graphs are not unambiguous, because circles in graphs can be
      52             :  * walked in either direction.
      53             :  */
      54             : 
      55             : /*
      56             :  * Field sizes for the random art.  Have to be odd, so the starting point
      57             :  * can be in the exact middle of the picture, and FLDBASE should be >=8 .
      58             :  * Else pictures would be too dense, and drawing the frame would
      59             :  * fail, too, because the key type would not fit in anymore.
      60             :  */
      61             : #define FLDBASE         8
      62             : #define FLDSIZE_Y       (FLDBASE + 1)
      63             : #define FLDSIZE_X       (FLDBASE * 2 + 1)
      64           3 : char *_gnutls_key_fingerprint_randomart(uint8_t * dgst_raw,
      65             :                                         u_int dgst_raw_len,
      66             :                                         const char *key_type,
      67             :                                         unsigned int key_size,
      68             :                                         const char *prefix)
      69             : {
      70             :         /*
      71             :          * Chars to be used after each other every time the worm
      72             :          * intersects with itself.  Matter of taste.
      73             :          */
      74           3 :         const char augmentation_string[] = " .o+=*BOX@%&#/^SE";
      75           3 :         char *retval, *p;
      76           3 :         uint8_t field[FLDSIZE_X][FLDSIZE_Y];
      77           3 :         char size_txt[16];
      78           3 :         unsigned int i, b;
      79           3 :         int x, y;
      80           3 :         const size_t len = sizeof(augmentation_string) - 2;
      81           3 :         unsigned int prefix_len = 0;
      82             : 
      83           3 :         if (prefix)
      84           0 :                 prefix_len = strlen(prefix);
      85             : 
      86           3 :         retval =
      87           6 :             gnutls_calloc(1,
      88           3 :                           (FLDSIZE_X + 3 + prefix_len) * (FLDSIZE_Y + 2));
      89           3 :         if (retval == NULL) {
      90           0 :                 gnutls_assert();
      91           0 :                 return NULL;
      92             :         }
      93             : 
      94             :         /* initialize field */
      95           3 :         memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
      96           3 :         x = FLDSIZE_X / 2;
      97           3 :         y = FLDSIZE_Y / 2;
      98             : 
      99             :         /* process raw key */
     100          75 :         for (i = 0; i < dgst_raw_len; i++) {
     101          72 :                 int input;
     102             :                 /* each byte conveys four 2-bit move commands */
     103          72 :                 input = dgst_raw[i];
     104         360 :                 for (b = 0; b < 4; b++) {
     105             :                         /* evaluate 2 bit, rest is shifted later */
     106         288 :                         x += (input & 0x1) ? 1 : -1;
     107         288 :                         y += (input & 0x2) ? 1 : -1;
     108             : 
     109             :                         /* assure we are still in bounds */
     110         288 :                         x = MAX(x, 0);
     111         288 :                         y = MAX(y, 0);
     112         288 :                         x = MIN(x, FLDSIZE_X - 1);
     113         288 :                         y = MIN(y, FLDSIZE_Y - 1);
     114             : 
     115             :                         /* augment the field */
     116         288 :                         if (field[x][y] < len - 2)
     117         288 :                                 field[x][y]++;
     118         288 :                         input = input >> 2;
     119             :                 }
     120             :         }
     121             : 
     122             :         /* mark starting point and end point */
     123           3 :         field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
     124           3 :         field[x][y] = len;
     125             : 
     126           3 :         if (key_size > 0)
     127           3 :                 snprintf(size_txt, sizeof(size_txt), " %4u", key_size);
     128             :         else
     129           0 :                 size_txt[0] = 0;
     130             : 
     131             :         /* fill in retval */
     132           3 :         if (prefix_len)
     133           0 :                 snprintf(retval, FLDSIZE_X + prefix_len, "%s+--[%4s%s]",
     134             :                          prefix, key_type, size_txt);
     135             :         else
     136           3 :                 snprintf(retval, FLDSIZE_X, "+--[%4s%s]", key_type,
     137             :                          size_txt);
     138           3 :         p = strchr(retval, '\0');
     139             : 
     140             :         /* output upper border */
     141          14 :         for (i = p - retval - 1; i < FLDSIZE_X + prefix_len; i++)
     142          11 :                 *p++ = '-';
     143           3 :         *p++ = '+';
     144           3 :         *p++ = '\n';
     145             : 
     146           3 :         if (prefix_len) {
     147           0 :                 memcpy(p, prefix, prefix_len);
     148           0 :                 p += prefix_len;
     149             :         }
     150             : 
     151             :         /* output content */
     152          30 :         for (y = 0; y < FLDSIZE_Y; y++) {
     153          27 :                 *p++ = '|';
     154         486 :                 for (x = 0; x < FLDSIZE_X; x++)
     155         459 :                         *p++ = augmentation_string[MIN(field[x][y], len)];
     156          27 :                 *p++ = '|';
     157          27 :                 *p++ = '\n';
     158             : 
     159          27 :                 if (prefix_len) {
     160           0 :                         memcpy(p, prefix, prefix_len);
     161           0 :                         p += prefix_len;
     162             :                 }
     163             :         }
     164             : 
     165             :         /* output lower border */
     166           3 :         *p++ = '+';
     167          54 :         for (i = 0; i < FLDSIZE_X; i++)
     168          51 :                 *p++ = '-';
     169           3 :         *p++ = '+';
     170             : 
     171           3 :         return retval;
     172             : }

Generated by: LCOV version 1.14