gpgfuncts.py 5.47 KB
Newer Older
putro's avatar
putro committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
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)

putro's avatar
putro committed
16

putro's avatar
putro committed
17 18 19 20 21 22 23
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
putro's avatar
putro committed
24 25 26 27 28
    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, )
putro's avatar
putro committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
    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"""
putro's avatar
putro committed
48 49
                if encrypt("test", k["fingerprint"],
                    test=True).status == "encryption ok":
putro's avatar
putro committed
50
                    key = True
putro's avatar
putro committed
51 52
                    config['last_message'] = "OK - key choosed: keyID=%s" \
                    % getKeyID(k["fingerprint"])
putro's avatar
putro committed
53 54 55
                    break

                else:
putro's avatar
putro committed
56 57
                    config['last_message'] = "ERROR - invalid key for " \
                        "recipient: %s" % u
putro's avatar
putro committed
58 59 60 61 62 63 64 65 66 67
                    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"]

putro's avatar
putro committed
68

putro's avatar
putro committed
69 70 71 72 73 74 75 76 77 78
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

putro's avatar
putro committed
79

putro's avatar
putro committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
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
putro's avatar
putro committed
100 101
                last_message = "OK - secret key choosed: keyID=%s" \
                    % config['nym_keyid']
putro's avatar
putro committed
102 103 104 105 106 107 108 109
                break
        if key:
            break
    if not key:
        config['last_message'] = "ERROR, secret key for %s NOT found" % email
        return False
    return k["fingerprint"]

putro's avatar
putro committed
110

putro's avatar
putro committed
111 112 113 114 115
def getKeyID(fp):
    """ Get keyid from fingeprint """
    # works only with v4 keys
    return fp[-8:]

putro's avatar
putro committed
116

putro's avatar
putro committed
117 118 119 120 121 122
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

putro's avatar
putro committed
123

putro's avatar
putro committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
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:
putro's avatar
putro committed
142 143
                print "there are only %d keys, select key number again" \
                % numkeys
putro's avatar
putro committed
144 145 146 147 148
                continue
            break
    a -= 1
    return ls[a]

putro's avatar
putro committed
149

putro's avatar
putro committed
150 151 152 153 154 155 156 157
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

putro's avatar
putro committed
158

putro's avatar
putro committed
159 160 161 162 163 164 165 166 167 168 169 170 171
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":
putro's avatar
putro committed
172 173
            config['last_message'] = "ERROR " + encrypted_ascii_data.status + \
            " (recipient: %s)" % recipient
174
            return "ERROR"
putro's avatar
putro committed
175 176 177
        else:
            return stripVersion(str(encrypted_ascii_data))
    else:
putro's avatar
putro committed
178
        return encrypted_ascii_data