keyring-splitting program
JanuszA.Urbanowicz
JanuszA.Urbanowicz
Sun Mar 24 18:41:02 2002
--ELM72123749-26264-0_
Content-Type: application/pgp; format=text; x-action=sign
Content-Transfer-Encoding: 8bit
-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160
Hello
I've written a small Python program/module to split my keyring into sepaarte
keys for rebuilding since it got corrupted. It is also useful for importing
large amounts of keys into PGP - all versions have problems with importing
large (>50) solid blobs of public keys. Since its a spinoff of generic gnupg
gnupg interface I'm writing, I named id gnupg.py, feel encouraged to rename
it as you like during installation.
I consider this a submission for the Project's tools directory.
Hope you will find the code useful.
Alex
- --
Janusz A. Urbanowicz | ALEX3-RIPE | SF-Framling | Thawte Web Of Trust Notary
Gdy daję biednym chleb, nazywają mnie świętym. Gdy pytam,
dlaczego biedni nie mają chleba, nazywają mnie komunistą. - abp. Helder Camara
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6d (GNU/Linux)
iD8DBQE8nhEdTfkBjn4ugD0RA+hJAJ9f/Zuv5kFG3EDkY2+sLmHYCgQ9lgCeJajl
V69/47wLvRSE/82UUyaOw4o=
=OZVm
-----END PGP SIGNATURE-----
--ELM72123749-26264-0_
Content-Type: text/plain; charset=ISO-8859-2
Content-Disposition: attachment; filename=gnupg.py
Content-Description: python program
Content-Transfer-Encoding: 7bit
#! /usr/bin/env python
'''Utility program for GNU Privacy Guard.
This code runs under Python 1.5.2 on GNU/Linux. It should run on newer
versions of Python as well. Some of the functions won't run on other
architectures.
Copyright 2002 Janusz A. Urbanowicz <alex@bofh.net.pl>
$Id: gnupg.py,v 1.2.1.5 2002/03/24 17:16:07 alex Exp $
This program is distributed under the terms opf GNU General Public License.
Version 2 or later.
When called as a program, exports every key in the public keyring to
a file named by the key's 64 bit key ID in binary or ascii armored form.
Optionally, binary mode and destination directory can be specified.
For usage info, run the program with -h parameter.
The program can be laso used as a Python module with following public
functions: listkeys(), listkey(), simpledecrypt() and recipients().
For description of those, refer to appropriate docstrings.
'''
import tempfile,os,re,popen2,sys,getopt,os.path
#
# Utility functions
#
def listkeys():
"Returns a dictionary of long-keyid (key) and primary UID (value) for default keyring)"
primaryre = re.compile('^pub:(?:-|u|r|f|d|m|q|e):[0-9]{3,4}?:(?:1|17):((?:[A-Z]|[0-9])+?):[0-9]{4}\-[0-9]{2}\-[0-9]{2}:(?:[0-9]{4}\-[0-9]{2}\-[0-9]{2})?:\w*?:\w*?:(.*?):\w*?:\w*?:')
secondaryre = re.compile('^uid:(?:-|u|r|f|d|m|q|e)::::::::(.*?):')
imagere = re.compile('^\[image of size [0-9]+?\]')
klucze = {}
gpghandle = os.popen('gpg --with-colons -k','r')
gpgoutput = gpghandle.readlines()
gpghandle.close()
for i in range(len(gpgoutput)):
result = primaryre.match(gpgoutput[i])
try:
keyid = result.groups()[0]
except AttributeError:
continue
klucze[keyid] = result.groups()[1]
if imagere.match(klucze[keyid]) == None:
continue
else:
klucze[keyid] = None
while primaryre.match(gpgoutput[i+1]) == None:
i = i+1
result = secondaryre.match(gpgoutput[i])
try:
klucze[keyid] = result.groups()[0]
assert imagere.match(klucze[keyid]) == None
break
except AttributeError,AssertionError:
pass
if klucze[keyid] == None:
del klucze[keyid]
del keyid
return klucze
def listkey(key):
"Returns a dictionary of long-keyid (key) and primary UID (value) for a single key."
primaryre = re.compile('^pub:(?:-|u|r|f|d|m|q|e):[0-9]{3,4}?:(?:1|17):((?:[A-Z]|[0-9])+?):[0-9]{4}\-[0-9]{2}\-[0-9]{2}:(?:[0-9]{4}\-[0-9]{2}\-[0-9]{2})?:\w*?:\w*?:(.*?):\w*?:\w*?:')
secondaryre = re.compile('^uid:(?:-|u|r|f|d|m|q|e)::::::::(.*?):')
imagere = re.compile('^\[image of size [0-9]+?\]')
klucze = {}
gpghandle = os.popen('gpg --with-colons -k %s' % key,'r')
gpgoutput = gpghandle.readlines()
gpghandle.close()
for i in range(len(gpgoutput)):
result = primaryre.match(gpgoutput[i])
try:
keyid = result.groups()[0]
except AttributeError:
continue
klucze[keyid] = result.groups()[1]
if imagere.match(klucze[keyid]) == None:
continue
else:
klucze[keyid] = None
while primaryre.match(gpgoutput[i+1]) == None:
i = i+1
result = secondaryre.match(gpgoutput[i])
try:
klucze[keyid] = result.groups()[0]
assert imagere.match(klucze[keyid]) == None
break
except AttributeError,AssertionError:
pass
if klucze[keyid] == None:
del klucze[keyid]
del keyid
return klucze
def simpledecrypt(passphrase,data):
'Decrypt PGP encrypted data with supplied passphrase, the result is the return value'
tempfilename = tempfile.mktemp()
tempfile = open(tempfilename,'w')
tempfile.write(data)
tempfile.close()
gpghandle = popen2.popen2('gpg --passphrase-fd 0 --batch --output - %s' % tempfilename)
gpghandle[1].write(passphrase)
gpghandle[1].close()
data = gpghandle[0].read()
gpghandle[0].close()
os.unlink(tempfilename)
return data
def recipients(data):
"Returns a tuple of key IDs the message is encrypted to. Based on the code from GnuPG FAQ."
gpghandle = popen2.popen2('gpg --batch --decrypt --list-only --status-fd 1')
gpghandle[1].write(data)
gpghandle[1].close()
results = gpghandle[0].readlines()
gpghandle[0].close()
recipientre = re.compile('^\[GNUPG:\] ENC_TO ((?:[A-Z]|[0-9]){16}) .*$',re.MULTILINE)
result = []
for line in results:
try:
match = recipientre.search(line).groups()
except AttributeError:
continue
result.append(match[0])
return tuple(result)
#
# Splitkeyring code.
#
if __name__ == '__main__':
dir = ''
mode = '--armor'
params,args = getopt.getopt(sys.argv[1:],'hd:b',['help','output-dir','binary'])
for param in params:
if '-h' in param or '--help' in param:
print '%s $Revision: 1.2.1.5 $\n' % sys.argv[0]
print 'Copyright 2002 Janusz A. Urbanowicz <alex@bofh.net.pl>.\n'
print 'This program is distributed under the terms of GNU General Public License.'
print 'Version 2 or later.\n'
print 'Synopsis: %s [-d | --output-dir <output dir>] [-b | --binary]' % sys.argv[0]
print '\nOptions: \n\n -d, --output-dir directtory to store the keys in (default: cwd)'
print ' -b, --binary export keys in binary form (default: off)'
print ' -h, --help this help message\n'
sys.exit(0)
if '-d' in param or '--output-dir' in param:
try:
dir = param[1]
except:
print 'No output directory supplied.'
sys.exit(1)
dir = os.path.abspath(dir)
if '-b' in param or '--binary' in param:
mode = ''
lkeys = listkeys()
for keyid in lkeys.keys():
file = open(os.path.join(dir,keyid),'w+')
if mode:
file.write('%s\n\n' % lkeys[keyid])
gpghandle = os.popen('gpg --quiet %s --batch --export %s' % (mode, keyid), 'r')
data = gpghandle.readlines()
gpghandle.close()
file.writelines(data)
file.close()
## Local Variables:
## mode: Python
## py-indent-offset: 2
## fill-column: 100
## End:
--ELM72123749-26264-0_
Content-Type: application/pgp
Content-Disposition: attachment; filename=gnupg.py.asc
Content-Description: detached signature file
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6d (GNU/Linux)
Comment: http://quiston.tpsa.com/~alex/pgp.html
iQCVAwUAPJ4Qerm/3a0nyBvJAQPbMQQAhKJQNmwYrEwd5Gk0dOJfvGL+UZM+aD4Q
FPHneoXj137/8fN+/0BgOY6FjRoAFxr1jJ6ErTO/INBJA5xulR6yhZNW5qRDDl/a
KuxzC1ptCcnFQNLNkUdbIMsqzjErPCffBtrgkMbg/ubTNPutKRNn3c8E+cFzFv24
i5TsumSSvZA=
=6beb
-----END PGP SIGNATURE-----
--ELM72123749-26264-0_--