gpgfuncts.py 5.31 KB
Newer Older
putro's avatar
putro committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
import sys
import re
import gnupg
import getpass
from config import config
from utils import pressKey



try:
    global gpg
    gpg = gnupg.GPG()
except:
    print "Error, problems with your keyring directory, exiting"
    sys.exit(0)

def createKey(email, name, comment="", key_type="RSA", key_length=4096):
    """ Create a gpg key """
    while True:
        pwd = getpass.getpass("insert the password: ")
        pwd2 = getpass.getpass("type again the password: ")
        if pwd == pwd2:
            break
    print "wait, I'm generating the key, move the mouse, press keys, it could take some times......\n"
    input_data = gpg.gen_key_input(name_real=name, name_email=email, name_comment="", passphrase=pwd, key_type=key_type, key_length=key_length, )
    key = gpg.gen_key(input_data)


def selectKey(email, secret=False):
    """ Select the key fingerprint of an email address"""
    keys = gpg.list_keys(secret=secret)
    key = False
    for k in keys:
        counter = 0
        # if keys have multiple uids, scan through all uids
        for u in k["uids"]:
            # stop at first match
            e = k["uids"][counter]
            counter += 1
            expr = re.compile("%s" % email)
            m = expr.search(e)
            """ if match found, select key """
            if m:
                """check if key is valid"""
                if encrypt("test", k["fingerprint"], test=True).status == "encryption ok":
                    key = True
                    config['last_message'] = "OK - key choosed: keyID=%s" % getKeyID(k["fingerprint"])
                    break

                else:
                    config['last_message'] = "ERROR - invalid key for recipient: %s" % u
                    key = False
        if key:
            break
    if not key:
        config['last_message'] = "ERROR, public key for %s NOT found" % email
        print "ERROR, public key for %s NOT found" % email
        pressKey()
        return False
    return k["fingerprint"]

def listSecKeys():
    """ Print list of secret keys in keyring"""
    seckeys = gpg.list_keys(secret=True)
    counter = 0
    for k in seckeys:
        counter += 1
        print "%s - %s - %s" % (counter, k["uids"][0], k["keyid"])
        print [x for x in k["uids"]]
    return seckeys

def selectSecKey(email):
    """ Select the key fingerprint of an email address"""
    global last_message
    seckeys = gpg.list_keys(True)
    key = False
    for k in seckeys:
        counter = 0
        """if keys have multiple uids, scan through all uids"""
        for u in k["uids"]:
            """stop at first match"""
            e = k["uids"][counter]
            counter += 1
            expr = re.compile("%s" % email)
            m = expr.search(e)
            """ if match found, select key """
            if m:
                #print "key fingerprint for %s: %s" % (email, k["fingerprint"])
                config['nym_fp'] = k["fingerprint"]
                config['nym_keyid'] = getKeyID(k["fingerprint"])
                key = True
                last_message = "OK - secret key choosed: keyID=%s" % config['nym_keyid']
                break
        if key:
            break
    if not key:
        config['last_message'] = "ERROR, secret key for %s NOT found" % email
        return False
    return k["fingerprint"]

def getKeyID(fp):
    """ Get keyid from fingeprint """
    # works only with v4 keys
    return fp[-8:]

def exportPubKey(id):
    """ Export public key
    id can be the fingerprint """
    ascii_armored_public_keys = stripVersion(str(gpg.export_keys(id)))
    return ascii_armored_public_keys

def defineSecKey():
    """ Select which secret key to use """
    ls = listSecKeys()
    numkeys = int(len(ls))
    print "there are %s keys" % numkeys
    if numkeys == 0:
        print "going to generate a new key..."
        createKey()
        listSecKeys()

    while True:
        a = raw_input("enter key number (and press enter): ")
        if a.isdigit():
            a = int(a)
            if a < 1:
                print "you can't enter a key number lower than 1"
                continue
            elif a > numkeys:
                print "there are only %d keys, select key number again" % numkeys
                continue
            break
    a -= 1
    return ls[a]

def deleteKey(fp):
    """ Delete secret and public key """
    global last_message
    seckey = gpg.list_keys(secret=True)
    str(gpg.delete_keys(fp, True))
    str(gpg.delete_keys(fp))
    last_message = "OK - key with fingerprint %s deleted" % fp

def stripVersion(pgptext):
    """Version strings in PGP blocks can weaken anonymity by partitioning users
    into subsets.  This function replaces the Version string with 'N/A'."""
    newtext = re.sub('(?m)^Version: .*', 'Version: N/A', pgptext)
    return newtext


def encrypt(message, recipient, sign=False, passphrase=False, test=False):
    """ Encrypt a message for a recipient """
    encrypted_ascii_data = gpg.encrypt(message, recipient, always_trust=True,
                                    sign=sign, passphrase=passphrase)
    if not test:
        if encrypted_ascii_data.status != "encryption ok":
            config['last_message'] = "ERROR " + encrypted_ascii_data.status + " (recipient: %s)" % recipient
            return False
        else:
            return stripVersion(str(encrypted_ascii_data))
    else:
        return encrypted_ascii_data