]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added function gnutls_random_art() to convert fingerprints to images (currently ascii...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 28 Dec 2011 14:12:17 +0000 (16:12 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 28 Dec 2011 14:23:24 +0000 (16:23 +0200)
NEWS
configure.ac
lib/Makefile.am
lib/extras/Makefile.am [new file with mode: 0644]
lib/extras/randomart.c [new file with mode: 0644]
lib/extras/randomart.h [new file with mode: 0644]
lib/gnutls_ui.c
lib/includes/gnutls/gnutls.h.in
lib/libgnutls.map
lib/openpgp/output.c
lib/x509/output.c

diff --git a/NEWS b/NEWS
index c04f2c80f7c47f31a09f56fa99afee8a4fdf07bb..be88c61c48dc60fd986558185889860536c7c36c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,8 +12,11 @@ in Linux as well as in BSD.
 ** libgnutls: Added ciphersuites: GNUTLS_PSK_WITH_AES_256_GCM_SHA384
 and GNUTLS_DHE_PSK_WITH_AES_256_GCM_SHA384.
 
+** libgnutls: Added function gnutls_random_art() to convert 
+fingerprints to images (currently ascii-art).
+
 ** API and ABI modifications:
-No changes since last version.
+gnutls_random_art: Added
 
 
 * Version 3.0.9 (released 2011-12-13)
index 2d3a359e08d0aa872fe9627a4de14f7a8ce2057f..ebc8625653e29f3b25e86f429c686b7e55f9d1fc 100644 (file)
@@ -465,6 +465,7 @@ AC_CONFIG_FILES([
   lib/algorithms/Makefile
   lib/auth/Makefile
   lib/ext/Makefile
+  lib/extras/Makefile
   lib/gnutls.pc
   lib/includes/Makefile
   lib/includes/gnutls/gnutls.h
index d944c2f7080e82fa58ca7fad53b57a881c4cdbfa..7fd533adab67b999ebb386661e80972fde371d29 100644 (file)
@@ -20,7 +20,7 @@
 
 ACLOCAL_AMFLAGS = -I ../m4 -I ../gl/m4
 
-SUBDIRS = includes x509 accelerated auth ext algorithms
+SUBDIRS = includes x509 accelerated auth ext algorithms extras
 if ENABLE_MINITASN1
 SUBDIRS += minitasn1
 endif
@@ -114,6 +114,7 @@ libgnutls_la_LDFLAGS = -no-undefined \
 libgnutls_la_LIBADD = ../gl/libgnu.la x509/libgnutls_x509.la \
        accelerated/libaccelerated.la ext/libgnutls_ext.la \
        auth/libgnutls_auth.la algorithms/libgnutls_alg.la \
+       extras/libgnutls_extras.la \
        $(LTLIBZ)  $(LTLIBINTL) $(LIBSOCKET) $(LTLIBDL) \
        $(LTLIBPTHREAD) $(P11_KIT_LIBS)
 
diff --git a/lib/extras/Makefile.am b/lib/extras/Makefile.am
new file mode 100644 (file)
index 0000000..b973b88
--- /dev/null
@@ -0,0 +1,37 @@
+## Process this file with automake to produce Makefile.in
+# Copyright (C) 2002-2011 Free Software Foundation, Inc.
+#
+# Author: Nikos Mavrogiannopoulos
+#
+# This file is part of GnuTLS.
+#
+# The GnuTLS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 3 of
+# the License, or (at your option) any later version.
+#
+# The GnuTLS is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>
+
+AM_CFLAGS = $(WERROR_CFLAGS) $(WSTACK_CFLAGS) $(WARN_CFLAGS)
+AM_CPPFLAGS = \
+       -I$(srcdir)/../../gl            \
+       -I$(builddir)/../../gl          \
+       -I$(srcdir)/../includes         \
+       -I$(builddir)/../includes       \
+       -I$(builddir)/../../gl          \
+       -I$(srcdir)/..                  \
+       -I$(srcdir)/../opencdk
+
+if ENABLE_MINITASN1
+AM_CPPFLAGS += -I$(srcdir)/../minitasn1
+endif
+
+noinst_LTLIBRARIES = libgnutls_extras.la
+
+libgnutls_extras_la_SOURCES = randomart.c
diff --git a/lib/extras/randomart.c b/lib/extras/randomart.c
new file mode 100644 (file)
index 0000000..c2ce08f
--- /dev/null
@@ -0,0 +1,147 @@
+/* $OpenBSD: key.c,v 1.98 2011/10/18 04:58:26 djm Exp $ */
+/*
+ * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <randomart.h>
+
+/*
+ * Draw an ASCII-Art representing the fingerprint so human brain can
+ * profit from its built-in pattern recognition ability.
+ * This technique is called "random art" and can be found in some
+ * scientific publications like this original paper:
+ *
+ * "Hash Visualization: a New Technique to improve Real-World Security",
+ * Perrig A. and Song D., 1999, International Workshop on Cryptographic
+ * Techniques and E-Commerce (CrypTEC '99)
+ * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
+ *
+ * The subject came up in a talk by Dan Kaminsky, too.
+ *
+ * If you see the picture is different, the key is different.
+ * If the picture looks the same, you still know nothing.
+ *
+ * The algorithm used here is a worm crawling over a discrete plane,
+ * leaving a trace (augmenting the field) everywhere it goes.
+ * Movement is taken from dgst_raw 2bit-wise.  Bumping into walls
+ * makes the respective movement vector be ignored for this turn.
+ * Graphs are not unambiguous, because circles in graphs can be
+ * walked in either direction.
+ */
+
+/*
+ * Field sizes for the random art.  Have to be odd, so the starting point
+ * can be in the exact middle of the picture, and FLDBASE should be >=8 .
+ * Else pictures would be too dense, and drawing the frame would
+ * fail, too, because the key type would not fit in anymore.
+ */
+#define        FLDBASE         8
+#define        FLDSIZE_Y       (FLDBASE + 1)
+#define        FLDSIZE_X       (FLDBASE * 2 + 1)
+char *
+key_fingerprint_randomart (uint8_t * dgst_raw, u_int dgst_raw_len,
+                           const char *key_type, unsigned int key_size)
+{
+  /*
+   * Chars to be used after each other every time the worm
+   * intersects with itself.  Matter of taste.
+   */
+  const char augmentation_string[] = " .o+=*BOX@%&#/^SE";
+  char *retval, *p;
+  uint8_t field[FLDSIZE_X][FLDSIZE_Y];
+  u_int i, b;
+  int x, y;
+  const size_t len = sizeof(augmentation_string) - 1;
+
+  retval = gnutls_calloc (1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2));
+  if (retval == NULL)
+    {
+      gnutls_assert();
+      return NULL;
+    }
+
+  /* initialize field */
+  memset (field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof (char));
+  x = FLDSIZE_X / 2;
+  y = FLDSIZE_Y / 2;
+
+  /* process raw key */
+  for (i = 0; i < dgst_raw_len; i++)
+    {
+      int input;
+      /* each byte conveys four 2-bit move commands */
+      input = dgst_raw[i];
+      for (b = 0; b < 4; b++)
+        {
+          /* evaluate 2 bit, rest is shifted later */
+          x += (input & 0x1) ? 1 : -1;
+          y += (input & 0x2) ? 1 : -1;
+
+          /* assure we are still in bounds */
+          x = MAX (x, 0);
+          y = MAX (y, 0);
+          x = MIN (x, FLDSIZE_X - 1);
+          y = MIN (y, FLDSIZE_Y - 1);
+
+          /* augment the field */
+          if (field[x][y] < len - 2)
+            field[x][y]++;
+          input = input >> 2;
+        }
+    }
+
+  /* mark starting point and end point */
+  field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
+  field[x][y] = len;
+
+  /* fill in retval */
+  snprintf (retval, FLDSIZE_X, "+--[%4s %4u]", key_type, key_size);
+  p = strchr (retval, '\0');
+
+  /* output upper border */
+  for (i = p - retval - 1; i < FLDSIZE_X; i++)
+    *p++ = '-';
+  *p++ = '+';
+  *p++ = '\n';
+
+  /* output content */
+  for (y = 0; y < FLDSIZE_Y; y++)
+    {
+      *p++ = '|';
+      for (x = 0; x < FLDSIZE_X; x++)
+        *p++ = augmentation_string[MIN (field[x][y], len)];
+      *p++ = '|';
+      *p++ = '\n';
+    }
+
+  /* output lower border */
+  *p++ = '+';
+  for (i = 0; i < FLDSIZE_X; i++)
+    *p++ = '-';
+  *p++ = '+';
+
+  return retval;
+}
diff --git a/lib/extras/randomart.h b/lib/extras/randomart.h
new file mode 100644 (file)
index 0000000..77d912b
--- /dev/null
@@ -0,0 +1,3 @@
+char *
+key_fingerprint_randomart (uint8_t * dgst_raw, u_int dgst_raw_len,
+                           const char *key_type, unsigned int key_size);
index edf80c096565daadb6def49cba1519a98f136221..6205a913810edfc4f0c3610906e26395105fdcd1 100644 (file)
 #include <gnutls_auth.h>
 #include <gnutls_state.h>
 #include <gnutls_datum.h>
+#include <extras/randomart.h>
+
+/**
+ * gnutls_random_art:
+ * @type: The type of the random art
+ * @key_type: The type of the key (RSA, DSA etc.)
+ * @key_size: The size of the key in bits
+ * @fpr: The fingerprint of the key
+ * @fpr_size: The size of the fingerprint
+ * @art: The returned random art
+ *
+ * This function will convert a given fingerprint to an "artistic"
+ * image. The returned image is allocated using gnutls_malloc()
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
+ *   an error code is returned.
+ *
+ **/
+int gnutls_random_art (gnutls_random_art_t type, 
+                       const char* key_type, unsigned int key_size,
+                       void * fpr, size_t fpr_size,
+                       gnutls_datum_t* art)
+{
+  if (type != GNUTLS_RANDOM_ART_OPENSSH)
+    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+  art->data = key_fingerprint_randomart(fpr, fpr_size, key_type, key_size);
+  if (art->data == NULL)
+    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+  
+  art->size = strlen(art->data);
+  
+  return 0;
+}
 
 /* ANON & DHE */
 
index 2906eaad3d659063041c3344ede30c5e1f873d13..3080dd01722745bd06fa4fdcf67e75e17fe3e4c1 100644 (file)
@@ -1268,13 +1268,21 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
   void gnutls_openpgp_send_cert (gnutls_session_t session,
                                  gnutls_openpgp_crt_status_t status);
 
-/* fingerprint 
- * Actually this function returns the hash of the given data.
+/* This function returns the hash of the given data.
  */
   int gnutls_fingerprint (gnutls_digest_algorithm_t algo,
                           const gnutls_datum_t * data, void *result,
                           size_t * result_size);
 
+  typedef enum gnutls_random_art
+  {
+    GNUTLS_RANDOM_ART_OPENSSH=1,
+  } gnutls_random_art_t;
+
+  int gnutls_random_art (gnutls_random_art_t type, 
+                         const char* key_name, unsigned int key_size,
+                         void * fpr, size_t fpr_size,
+                         gnutls_datum_t* art);
 
 /* SRP 
  */
index 24f04f0d7420981e918d2081223908b083565a53..04772105db055386bc70f41c295f8bcc4a5ce78f 100644 (file)
@@ -726,6 +726,7 @@ GNUTLS_3_0_0 {
        gnutls_srp_4096_group_prime;
        gnutls_x509_privkey_verify_params;
        gnutls_priority_get_cipher_suite_index;
+       gnutls_random_art;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
index 2b5f12d59281f74e14769ae7944423aabd8bcdaf..defcf95f04fa622e2c867b75fa9804fa85fbcd74 100644 (file)
@@ -26,6 +26,7 @@
 #include <gnutls_int.h>
 #include <gnutls/openpgp.h>
 #include <gnutls_errors.h>
+#include <extras/randomart.h>
 
 /* I18n of error codes. */
 #include "gettext.h"
@@ -88,6 +89,7 @@ print_key_id (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert, int idx)
       _gnutls_buffer_hexprint (str, id, sizeof (id));
       addf (str, "\n");
     }
+
 }
 
 /* idx == -1 indicates main key
@@ -99,6 +101,9 @@ print_key_fingerprint (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert)
   char fpr[128];
   size_t fpr_size = sizeof (fpr);
   int err;
+  const char* name;
+  char* p;
+  unsigned int bits;
 
   err = gnutls_openpgp_crt_get_fingerprint (cert, fpr, &fpr_size);
   if (err < 0)
@@ -109,6 +114,24 @@ print_key_fingerprint (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert)
       _gnutls_buffer_hexprint (str, fpr, fpr_size);
       addf (str, "\n");
     }
+
+  err = gnutls_openpgp_crt_get_pk_algorithm (cert, &bits);
+  if (err < 0)
+    return;
+    
+  name = gnutls_pk_get_name(err);
+  if (name == NULL)
+    return;
+
+  p = key_fingerprint_randomart(fpr, fpr_size, name, bits);
+  if (p == NULL)
+    return;
+  
+  adds (str, _("\trandomart:\n"));
+  adds (str, p);
+  adds (str, "\n");
+
+  gnutls_free(p);
 }
 
 static void
index b0e864096678e572231863c4f88ade04431b1875..894f56a1123f0d40cbbcec15d9bca762a776c98e 100644 (file)
@@ -29,6 +29,7 @@
 #include <x509_int.h>
 #include <gnutls_num.h>
 #include <gnutls_errors.h>
+#include <extras/randomart.h>
 
 /* I18n of error codes. */
 #include "gettext.h"
@@ -1348,7 +1349,10 @@ print_fingerprint (gnutls_buffer_st * str, gnutls_x509_crt_t cert,
   int err;
   char buffer[MAX_HASH_SIZE];
   size_t size = sizeof (buffer);
-
+  const char* name;
+  char* p;
+  unsigned int bits;
+  
   err = gnutls_x509_crt_get_fingerprint (cert, algo, buffer, &size);
   if (err < 0)
     {
@@ -1362,6 +1366,24 @@ print_fingerprint (gnutls_buffer_st * str, gnutls_x509_crt_t cert,
     adds (str, _("\tSHA-1 fingerprint:\n\t\t"));
   _gnutls_buffer_hexprint (str, buffer, size);
   adds (str, "\n");
+
+  err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
+  if (err < 0)
+    return;
+    
+  name = gnutls_pk_get_name(err);
+  if (name == NULL)
+    return;
+
+  p = key_fingerprint_randomart(buffer, size, name, bits);
+  if (p == NULL)
+    return;
+  
+  adds (str, _("\trandomart:\n"));
+  adds (str, p);
+  adds (str, "\n");
+
+  gnutls_free(p);
 }
 
 static void