summaryrefslogtreecommitdiff
path: root/key.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2008-06-13 04:40:35 +1000
committerDarren Tucker <dtucker@zip.com.au>2008-06-13 04:40:35 +1000
commit9c16ac926376ad87084ae78bac44a813ae5db21f (patch)
tree438b335d17d91d45c9c77fba9339816b2bf2dbf9 /key.c
parent1199673393661ceafc3141e5df43c53e9acdba2f (diff)
- grunk@cvs.openbsd.org 2008/06/11 21:01:35
[ssh_config.5 key.h readconf.c readconf.h ssh-keygen.1 ssh-keygen.c key.c sshconnect.c] Introduce SSH Fingerprint ASCII Visualization, a technique inspired by the graphical hash visualization schemes known as "random art", and by Dan Kaminsky's musings on the subject during a BlackOp talk at the 23C3 in Berlin. Scientific publication (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) http://sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf 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, thus switching to the other color of the chessboard. Graphs are not unambiguous for now, because circles in graphs can be walked in either direction. discussions with several people, help, corrections and ok markus@ djm@
Diffstat (limited to 'key.c')
-rw-r--r--key.c105
1 files changed, 104 insertions, 1 deletions
diff --git a/key.c b/key.c
index 62bf8361d..5d357a8d6 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.c,v 1.69 2007/07/12 05:48:05 ray Exp $ */ 1/* $OpenBSD: key.c,v 1.70 2008/06/11 21:01:35 grunk Exp $ */
2/* 2/*
3 * read_bignum(): 3 * read_bignum():
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,6 +35,7 @@
35 35
36#include "includes.h" 36#include "includes.h"
37 37
38#include <sys/param.h>
38#include <sys/types.h> 39#include <sys/types.h>
39 40
40#include <openssl/evp.h> 41#include <openssl/evp.h>
@@ -295,6 +296,105 @@ key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
295 return retval; 296 return retval;
296} 297}
297 298
299/*
300 * Draw an ASCII-Art representing the fingerprint so human brain can
301 * profit from its built-in pattern recognition ability.
302 * This technique is called "random art" and can be found in some
303 * scientific publications like this original paper:
304 *
305 * "Hash Visualization: a New Technique to improve Real-World Security",
306 * Perrig A. and Song D., 1999, International Workshop on Cryptographic
307 * Techniques and E-Commerce (CrypTEC '99)
308 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
309 *
310 * The subject came up in a talk by Dan Kaminsky, too.
311 *
312 * If you see the picture is different, the key is different.
313 * If the picture looks the same, you still know nothing.
314 *
315 * The algorithm used here is a worm crawling over a discrete plane,
316 * leaving a trace (augmenting the field) everywhere it goes.
317 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls
318 * makes the respective movement vector be ignored for this turn.
319 * Graphs are not unambiguous, because circles in graphs can be
320 * walked in either direction.
321 */
322#define FLDSIZE_Y 8
323#define FLDSIZE_X FLDSIZE_Y * 2
324static char *
325key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len)
326{
327 /*
328 * Chars to be used after each other every time the worm
329 * intersects with itself. Matter of taste.
330 */
331 char *augmentation_string = " .o+=*BOX@%&#/^";
332 char *retval, *p;
333 char field[FLDSIZE_X][FLDSIZE_Y];
334 u_int i, b;
335 int x, y;
336
337 retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2));
338
339 /* initialize field */
340 memset(field, ' ', FLDSIZE_X * FLDSIZE_Y * sizeof(char));
341 x = FLDSIZE_X / 2;
342 y = FLDSIZE_Y / 2;
343 field[x][y] = '.';
344
345 /* process raw key */
346 for (i = 0; i < dgst_raw_len; i++) {
347 int input;
348 /* each byte conveys four 2-bit move commands */
349 input = dgst_raw[i];
350 for (b = 0; b < 4; b++) {
351 /* evaluate 2 bit, rest is shifted later */
352 x += (input & 0x1) ? 1 : -1;
353 y += (input & 0x2) ? 1 : -1;
354
355 /* assure we are still in bounds */
356 x = MAX(x, 0);
357 y = MAX(y, 0);
358 x = MIN(x, FLDSIZE_X - 1);
359 y = MIN(y, FLDSIZE_Y - 1);
360
361 /* augment the field */
362 p = strchr(augmentation_string, field[x][y]);
363 if (*++p != '\0')
364 field[x][y] = *p;
365
366 input = input >> 2;
367 }
368 }
369
370 /* fill in retval */
371 p = retval;
372
373 /* output upper border */
374 *p++ = '+';
375 for (i = 0; i < FLDSIZE_X; i++)
376 *p++ = '-';
377 *p++ = '+';
378 *p++ = '\n';
379
380 /* output content */
381 for (y = 0; y < FLDSIZE_Y; y++) {
382 *p++ = '|';
383 for (x = 0; x < FLDSIZE_X; x++)
384 *p++ = field[x][y];
385 *p++ = '|';
386 *p++ = '\n';
387 }
388
389 /* output lower border */
390 *p++ = '+';
391 for (i = 0; i < FLDSIZE_X; i++)
392 *p++ = '-';
393 *p++ = '+';
394
395 return retval;
396}
397
298char * 398char *
299key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) 399key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
300{ 400{
@@ -312,6 +412,9 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
312 case SSH_FP_BUBBLEBABBLE: 412 case SSH_FP_BUBBLEBABBLE:
313 retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 413 retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
314 break; 414 break;
415 case SSH_FP_RANDOMART:
416 retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len);
417 break;
315 default: 418 default:
316 fatal("key_fingerprint_ex: bad digest representation %d", 419 fatal("key_fingerprint_ex: bad digest representation %d",
317 dgst_rep); 420 dgst_rep);