[Pgp-tools-commit] r620 - trunk/keyart

Aaron Toponce atoponce-guest at moszumanska.debian.org
Wed May 14 22:02:28 UTC 2014


Author: atoponce-guest
Date: 2014-05-14 22:02:28 +0000 (Wed, 14 May 2014)
New Revision: 620

Modified:
   trunk/keyart/keyart
Log:
Implement upstream bug work around and multiple key support.

See upstream bug #1640:
    - https://bugs.g10code.com/gnupg/issue1640

Also implement the ability to process multiple keys on the command line.


Modified: trunk/keyart/keyart
===================================================================
--- trunk/keyart/keyart	2014-05-14 19:46:53 UTC (rev 619)
+++ trunk/keyart/keyart	2014-05-14 22:02:28 UTC (rev 620)
@@ -1,159 +1,181 @@
 #!/usr/bin/env python
 
 import os
+import re   # needed only for work around
 import subprocess
 import sys
 
-try:
-    keyfile = sys.argv[1]
-except IndexError:
-    print "Usage: keyart /path/to/exported-key"
-    sys.exit(1)
+def draw_art(keyfile):
+    if not os.path.isfile(keyfile):
+        print "No such file or directory: {0}".format(keyfile)
+        sys.exit(2)
+    elif not os.access(keyfile, os.R_OK):
+        print "{0} is not readable. Check permissions.".format(keyfile)
+        sys.exit(3)
 
-if not os.path.isfile(keyfile):
-    print "No such file or directory: {0}".format(keyfile)
-    sys.exit(2)
-elif not os.access(keyfile, os.R_OK):
-    print "{0} is not readable. Check permissions.".format(keyfile)
-    sys.exit(3)
+    try:
+        if os.access('/usr/bin/gpg',os.X_OK):
+            gpg_bin = '/usr/bin/gpg'
+        else:
+            gpg_bin = '/usr/bin/gpg2'
 
-try:
-    if os.access('/usr/bin/gpg',os.X_OK):
-        gpg_bin = '/usr/bin/gpg'
-    else:
-        gpg_bin = '/usr/bin/gpg2'
+        DEVNULL = open(os.devnull, 'wb')
+        gpg = subprocess.Popen(
+            (gpg_bin,'--with-fingerprint','--with-colons', keyfile),
+            stdout=subprocess.PIPE, stderr=DEVNULL)
+        out = gpg.communicate()
+        DEVNULL.close()
+    except OSError:
+        print "Please install GnuPG before using this script."
+        sys.exit(4)
 
-    DEVNULL = open(os.devnull, 'wb')
-    gpg = subprocess.Popen(
-        (gpg_bin,'--with-fingerprint','--with-colons', keyfile),
-        stdout=subprocess.PIPE, stderr=DEVNULL)
-    out = gpg.communicate()
-    DEVNULL.close()
-except OSError:
-    print "Please install GnuPG before using this script."
-    sys.exit(4)
+    try:
+        key_size = [i.strip() for i in out[0].split(':')][2]
+        key_algo = [i.strip() for i in out[0].split(':')][3]
+        key_fpr = [i.strip() for i in out[0].split(':')][19]
 
-try:
-    key_size = [i.strip() for i in out[0].split(':')][2]
-    key_algo = [i.strip() for i in out[0].split(':')][3]
-    key_fpr = [i.strip() for i in out[0].split(':')][19]
-except IndexError:
-    print "It appears that {0} is not an exported public PGP key.".format(keyfile)
-    sys.exit(5)
+        ### BEGIN ugly work around for GnuPG bug #1640
+        # See: https://bugs.g10code.com/gnupg/issue1640
+        pattern = re.compile('[A-Z0-9]{40}')
 
-coin = ''
-f_bytes = []
-pos = 104
-walk = [pos]
-visits = [0]*209
-coins = [' ','.','^',':','l','i','?','{','f','x','X','Z','#','M','W','&','8','%','@']
+        if not pattern.match(key_fpr):
+            DEVNULL = open(os.devnull, 'wb')
+            gpg = subprocess.Popen((gpg_bin,'--import',keyfile), stderr=DEVNULL)
+            out = gpg.communicate()
+            gpg = subprocess.Popen(
+                (gpg_bin,'--fingerprint','--with-colons',os.path.splitext(keyfile)[0]),
+                stdout=subprocess.PIPE)
+            out = gpg.communicate()
+            DEVNULL.close()
+            key_fpr = [i.strip() for i in out[0].split(':')][28]
+        ### END ugly work around
 
-zfill = str.zfill
+    except IndexError:
+        print "It appears that {0} is not an exported public PGP key.".format(keyfile)
+        sys.exit(5)
 
-for c in key_fpr:
-    f_bytes.append(zfill(bin(int(c,16))[2:],4)[:2]) # last 2 bits
-    f_bytes.append(zfill(bin(int(c,16))[2:],4)[2:]) # first 2 bits
+    coin = ''
+    f_bytes = []
+    pos = 104
+    walk = [pos]
+    visits = [0]*209
+    coins = [' ','.','^',':','l','i','?','{','f','x','X','Z','#','M','W','&','8','%','@']
 
-# I break from the OpenSSH implementation here. Rather than reading the
-# bytes in little endian, the code is simpler reading in big endian. I
-# don't see the point in complicating the code for little endian reading,
-# when the fingerprint is SHA1 output, and should provide random output.
-for d in f_bytes:
-    if (20 <= pos <=  36 or  39 <= pos <=  55 or  58 <= pos <=  74 or
-        77 <= pos <=  93 or  96 <= pos <= 112 or 115 <= pos <= 131 or
-       134 <= pos <= 150 or 153 <= pos <= 169 or 172 <= pos <= 188):
-        if   d == '00': pos -= 20 # Square 'M'
-        elif d == '01': pos -= 18
-        elif d == '10': pos += 18
-        else: pos += 20
-    elif 1 <= pos <= 17: # Square 'T'
-        if   d == '00': pos -= 1
-        elif d == '01': pos += 1
-        elif d == '10': pos += 18
-        else: pos += 20
-    elif 191 <= pos <= 207: # Square 'B'
-        if   d == '00': pos -= 20
-        elif d == '01': pos -= 18
-        elif d == '10': pos -= 1
-        else: pos += 1
-    elif pos in [19, 38, 57, 76, 95, 114, 133, 152, 171]: # Square 'L'
-        if   d == '00': pos -= 19
-        elif d == '01': pos -= 18
-        elif d == '10': pos += 19
-        else: pos += 20
-    elif pos in [37, 56, 75, 94, 113, 132, 151, 170, 189]: # Square 'R'
-        if   d == '00': pos -= 20
-        elif d == '01': pos -= 19
-        elif d == '10': pos += 18
-        else: pos += 19
-    elif pos == 0: # Square 'a'
-        if   d == '01': pos += 1
-        elif d == '10': pos += 19
-        elif d == '11': pos += 20
-    elif pos == 18: # Square 'b'
-        if   d == '00': pos -= 1
-        elif d == '10': pos += 18
-        elif d == '11': pos += 19
-    elif pos == 190: # Square 'c'
-        if   d == '00': pos -= 19
-        elif d == '01': pos -= 18
-        elif d == '11': pos += 1
-    else: # Square 'd'
-        if   d == '00': pos -= 20
-        elif d == '01': pos -= 19
-        elif d == '10': pos -= 1
-    walk.append(pos)
+    zfill = str.zfill
 
-for w in walk:
-    visits[w] += 1
-    if visits[w] > 18: visits[w] = 18
+    for c in key_fpr:
+        f_bytes.append(zfill(bin(int(c,16))[2:],4)[:2]) # last 2 bits
+        f_bytes.append(zfill(bin(int(c,16))[2:],4)[2:]) # first 2 bits
+            
+            
 
-# See https://tools.ietf.org/html/rfc4880#section-9.1
-# Also https://tools.ietf.org/html/rfc6637#section4
-if key_algo == '17':
-    key_algo = 'DSA'
-elif key_algo == '1' or key_algo == '2' or key_algo == '3':
-    key_algo = 'RSA'
-elif key_algo == '16' or key_algo == '20':
-    key_algo = 'Elg'
-elif key_algo == '18':
-    key_algo = 'ECDH'
-elif key_algo == '19':
-    key_algo = 'ECDSA'
-elif key_algo == '21':
-    key_algo = 'X9.42'
-else: key_algo = 'N/A'
+    # I break from the OpenSSH implementation here. Rather than reading the
+    # bytes in little endian, the code is simpler reading in big endian. I
+    # don't see the point in complicating the code for little endian reading,
+    # when the fingerprint is SHA1 output, and should provide random output.
+    for d in f_bytes:
+        if (20 <= pos <=  36 or  39 <= pos <=  55 or  58 <= pos <=  74 or
+            77 <= pos <=  93 or  96 <= pos <= 112 or 115 <= pos <= 131 or
+           134 <= pos <= 150 or 153 <= pos <= 169 or 172 <= pos <= 188):
+            if   d == '00': pos -= 20 # Square 'M'
+            elif d == '01': pos -= 18
+            elif d == '10': pos += 18
+            else: pos += 20
+        elif 1 <= pos <= 17: # Square 'T'
+            if   d == '00': pos -= 1
+            elif d == '01': pos += 1
+            elif d == '10': pos += 18
+            else: pos += 20
+        elif 191 <= pos <= 207: # Square 'B'
+            if   d == '00': pos -= 20
+            elif d == '01': pos -= 18
+            elif d == '10': pos -= 1
+            else: pos += 1
+        elif pos in [19, 38, 57, 76, 95, 114, 133, 152, 171]: # Square 'L'
+            if   d == '00': pos -= 19
+            elif d == '01': pos -= 18
+            elif d == '10': pos += 19
+            else: pos += 20
+        elif pos in [37, 56, 75, 94, 113, 132, 151, 170, 189]: # Square 'R'
+            if   d == '00': pos -= 20
+            elif d == '01': pos -= 19
+            elif d == '10': pos += 18
+            else: pos += 19
+        elif pos == 0: # Square 'a'
+            if   d == '01': pos += 1
+            elif d == '10': pos += 19
+            elif d == '11': pos += 20
+        elif pos == 18: # Square 'b'
+            if   d == '00': pos -= 1
+            elif d == '10': pos += 18
+            elif d == '11': pos += 19
+        elif pos == 190: # Square 'c'
+            if   d == '00': pos -= 19
+            elif d == '01': pos -= 18
+            elif d == '11': pos += 1
+        else: # Square 'd'
+            if   d == '00': pos -= 20
+            elif d == '01': pos -= 19
+            elif d == '10': pos -= 1
+        walk.append(pos)
 
-if len("["+key_algo+" "+key_size+"]") == 10:
-    print '+----[{0} {1}]-----+'.format(key_algo, key_size)
-elif len("["+key_algo+" "+key_size+"]") == 11:
-    print '+----[{0} {1}]----+'.format(key_algo, key_size)
-elif len("["+key_algo+" "+key_size+"]") == 9:
-    print '+-----[{0} {1}]-----+'.format(key_algo, key_size)
-elif len("["+key_algo+" "+key_size+"]") == 12:
-    print '+---[{0} {1}]----+'.format(key_algo, key_size)
-elif len("["+key_algo+" "+key_size+"]") == 13:
-    print '+---[{0} {1}]---+'.format(key_algo, key_size)
-elif len("["+key_algo+" "+key_size+"]") == 14:
-    print '+--[{0} {1}]---+'.format(key_algo, key_size)
-elif len("["+key_algo+" "+key_size+"]") == 15:
-    print '+--[{0} {1}]--+'.format(key_algo, key_size)
-elif len("["+key_algo+" "+key_size+"]") == 16:
-    print '+-[{0} {1}]--+'.format(key_algo, key_size)
-elif len("["+key_algo+" "+key_size+"]") == 17:
-    print '+-[{0} {1}]-+'.format(key_algo, key_size)
-else:
-    print '+-------------------+'
+    for w in walk:
+        visits[w] += 1
+        if visits[w] > 18: visits[w] = 18
 
-for i, v in enumerate(visits):
-    coin += coins[v]
-    if i % 19 == 0:
-        coin = "|%s" % coin
-    if i == 104:
-        coin = "%sS" % coin[:10]
-    if i == walk[len(walk)-1]:
-        coin = "%sE" % coin[:len(coin)-1]
-    if i % 19 == 18:
-        print "%s|" % coin
-        coin = ''
-print '+----[{0}]-----+'.format(key_fpr[-8:])
+    # See https://tools.ietf.org/html/rfc4880#section-9.1
+    # Also https://tools.ietf.org/html/rfc6637#section4
+    if key_algo == '17':
+        key_algo = 'DSA'
+    elif key_algo == '1' or key_algo == '2' or key_algo == '3':
+        key_algo = 'RSA'
+    elif key_algo == '16' or key_algo == '20':
+        key_algo = 'Elg'
+    elif key_algo == '18':
+        key_algo = 'ECDH'
+    elif key_algo == '19':
+        key_algo = 'ECDSA'
+    elif key_algo == '21':
+        key_algo = 'X9.42'
+    else: key_algo = 'N/A'
+
+    if len("["+key_algo+" "+key_size+"]") == 10:
+        print '+----[{0} {1}]-----+'.format(key_algo, key_size)
+    elif len("["+key_algo+" "+key_size+"]") == 11:
+        print '+----[{0} {1}]----+'.format(key_algo, key_size)
+    elif len("["+key_algo+" "+key_size+"]") == 9:
+        print '+-----[{0} {1}]-----+'.format(key_algo, key_size)
+    elif len("["+key_algo+" "+key_size+"]") == 12:
+        print '+---[{0} {1}]----+'.format(key_algo, key_size)
+    elif len("["+key_algo+" "+key_size+"]") == 13:
+        print '+---[{0} {1}]---+'.format(key_algo, key_size)
+    elif len("["+key_algo+" "+key_size+"]") == 14:
+        print '+--[{0} {1}]---+'.format(key_algo, key_size)
+    elif len("["+key_algo+" "+key_size+"]") == 15:
+        print '+--[{0} {1}]--+'.format(key_algo, key_size)
+    elif len("["+key_algo+" "+key_size+"]") == 16:
+        print '+-[{0} {1}]--+'.format(key_algo, key_size)
+    elif len("["+key_algo+" "+key_size+"]") == 17:
+        print '+-[{0} {1}]-+'.format(key_algo, key_size)
+    else:
+        print '+-------------------+'
+
+    for i, v in enumerate(visits):
+        coin += coins[v]
+        if i % 19 == 0:
+            coin = "|%s" % coin
+        if i == 104:
+            coin = "%sS" % coin[:10]
+        if i == walk[len(walk)-1]:
+            coin = "%sE" % coin[:len(coin)-1]
+        if i % 19 == 18:
+            print "%s|" % coin
+            coin = ''
+    print '+----[{0}]-----+'.format(key_fpr[-8:])
+
+try:
+    for key in sys.argv[1:]:
+        draw_art(key)
+except IndexError:
+    print "Usage: keyart FILE [FILE [FILE ...]]"
+    sys.exit(1)




More information about the Pgp-tools-commit mailing list