python: HKP search and import updates

* Tweaked the code again so that it can also handle the cases where
  someone has included a hexadecimal string in their user ID.
* Updated the HOWTO to match.
* Exported to .rst and .texi.
This commit is contained in:
Ben McGinnes 2018-12-11 07:14:28 +11:00
parent fe7e01d164
commit 2e7a14c9b3
4 changed files with 212 additions and 50 deletions

View File

@ -932,6 +932,14 @@ IDs (e.g. ``0xDEADBEEF``) should no longer be used due to the relative
ease by which such key IDs can be reproduced, as demonstrated by the ease by which such key IDs can be reproduced, as demonstrated by the
Evil32 Project in 2014 (which was subsequently exploited in 2016). Evil32 Project in 2014 (which was subsequently exploited in 2016).
Testing for whether a string in any given search is or may be a
hexadecimal value which may be missing the leading ``0x`` is a simple
matter of using a try/except statement which attempts to convert the
string as hex to an integer and then back to hex; then using that to
search with. Raising a ValueError simply results in treating the string
as a string. This is the method and logic utilised in the
``import-keys-hkp.py`` script (see below).
.. _import-protonmail: .. _import-protonmail:
Working with ProtonMail Working with ProtonMail
@ -1068,6 +1076,7 @@ the keys found.
c = gpg.Context() c = gpg.Context()
server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net") server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
results = [] results = []
keys = []
if len(sys.argv) > 2: if len(sys.argv) > 2:
pattern = " ".join(sys.argv[1:]) pattern = " ".join(sys.argv[1:])
@ -1076,22 +1085,56 @@ the keys found.
else: else:
pattern = input("Enter the pattern to search for keys or user IDs: ") pattern = input("Enter the pattern to search for keys or user IDs: ")
try:
keys = server.search(pattern)
print("Found {0} key(s).".format(len(keys)))
except Exception as e:
keys = []
for logrus in pattern.split():
if logrus.startswith("0x") is True:
key = server.search(logrus)
else:
key = server.search("0x{0}".format(logrus))
keys.append(key[0])
print("Found {0} key(s).".format(len(keys)))
for key in keys: if pattern is not None:
import_result = c.key_import(key.key_blob) try:
results.append(import_result) key = server.search(hex(int(pattern, 16)))
keyed = True
except ValueError as ve:
key = server.search(pattern)
keyed = False
if key is not None:
keys.append(key[0])
if keyed is True:
try:
fob = server.search(pattern)
except:
fob = None
if fob is not None:
keys.append(fob[0])
else:
pass
else:
pass
for logrus in pattern.split():
try:
key = server.search(hex(int(logrus, 16)))
hexed = True
except ValueError as ve:
key = server.search(logrus)
hexed = False
if key is not None:
keys.append(key[0])
if hexed is True:
try:
fob = server.search(logrus)
except:
fob = None
if fob is not None:
keys.append(fob[0])
else:
pass
else:
pass
if len(keys) > 0:
for key in keys:
import_result = c.key_import(key.key_blob)
results.append(import_result)
for result in results: for result in results:
if result is not None and hasattr(result, "considered") is False: if result is not None and hasattr(result, "considered") is False:

View File

@ -963,6 +963,14 @@ relative ease by which such key IDs can be reproduced, as demonstrated
by the Evil32 Project in 2014 (which was subsequently exploited in by the Evil32 Project in 2014 (which was subsequently exploited in
2016). 2016).
Testing for whether a string in any given search is or may be a
hexadecimal value which may be missing the leading =0x= is a simple
matter of using a try/except statement which attempts to convert the
string as hex to an integer and then back to hex; then using that to
search with. Raising a ValueError simply results in treating the
string as a string. This is the method and logic utilised in the
=import-keys-hkp.py= script (see below).
*** Working with ProtonMail *** Working with ProtonMail
:PROPERTIES: :PROPERTIES:
@ -1097,6 +1105,7 @@ import sys
c = gpg.Context() c = gpg.Context()
server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net") server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
results = [] results = []
keys = []
if len(sys.argv) > 2: if len(sys.argv) > 2:
pattern = " ".join(sys.argv[1:]) pattern = " ".join(sys.argv[1:])
@ -1105,22 +1114,56 @@ elif len(sys.argv) == 2:
else: else:
pattern = input("Enter the pattern to search for keys or user IDs: ") pattern = input("Enter the pattern to search for keys or user IDs: ")
try:
keys = server.search(pattern)
print("Found {0} key(s).".format(len(keys)))
except Exception as e:
keys = []
for logrus in pattern.split():
if logrus.startswith("0x") is True:
key = server.search(logrus)
else:
key = server.search("0x{0}".format(logrus))
keys.append(key[0])
print("Found {0} key(s).".format(len(keys)))
for key in keys: if pattern is not None:
import_result = c.key_import(key.key_blob) try:
results.append(import_result) key = server.search(hex(int(pattern, 16)))
keyed = True
except ValueError as ve:
key = server.search(pattern)
keyed = False
if key is not None:
keys.append(key[0])
if keyed is True:
try:
fob = server.search(pattern)
except:
fob = None
if fob is not None:
keys.append(fob[0])
else:
pass
else:
pass
for logrus in pattern.split():
try:
key = server.search(hex(int(logrus, 16)))
hexed = True
except ValueError as ve:
key = server.search(logrus)
hexed = False
if key is not None:
keys.append(key[0])
if hexed is True:
try:
fob = server.search(logrus)
except:
fob = None
if fob is not None:
keys.append(fob[0])
else:
pass
else:
pass
if len(keys) > 0:
for key in keys:
import_result = c.key_import(key.key_blob)
results.append(import_result)
for result in results: for result in results:
if result is not None and hasattr(result, "considered") is False: if result is not None and hasattr(result, "considered") is False:

View File

@ -1134,6 +1134,14 @@ relative ease by which such key IDs can be reproduced, as demonstrated
by the Evil32 Project in 2014 (which was subsequently exploited in by the Evil32 Project in 2014 (which was subsequently exploited in
2016). 2016).
Testing for whether a string in any given search is or may be a
hexadecimal value which may be missing the leading @samp{0x} is a simple
matter of using a try/except statement which attempts to convert the
string as hex to an integer and then back to hex; then using that to
search with. Raising a ValueError simply results in treating the
string as a string. This is the method and logic utilised in the
@samp{import-keys-hkp.py} script (see below).
@menu @menu
* Working with ProtonMail:: * Working with ProtonMail::
* Importing with HKP for Python:: * Importing with HKP for Python::
@ -1268,6 +1276,7 @@ import sys
c = gpg.Context() c = gpg.Context()
server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net") server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
results = [] results = []
keys = []
if len(sys.argv) > 2: if len(sys.argv) > 2:
pattern = " ".join(sys.argv[1:]) pattern = " ".join(sys.argv[1:])
@ -1276,22 +1285,56 @@ elif len(sys.argv) == 2:
else: else:
pattern = input("Enter the pattern to search for keys or user IDs: ") pattern = input("Enter the pattern to search for keys or user IDs: ")
try:
keys = server.search(pattern)
print("Found @{0@} key(s).".format(len(keys)))
except Exception as e:
keys = []
for logrus in pattern.split():
if logrus.startswith("0x") is True:
key = server.search(logrus)
else:
key = server.search("0x@{0@}".format(logrus))
keys.append(key[0])
print("Found @{0@} key(s).".format(len(keys)))
for key in keys: if pattern is not None:
import_result = c.key_import(key.key_blob) try:
results.append(import_result) key = server.search(hex(int(pattern, 16)))
keyed = True
except ValueError as ve:
key = server.search(pattern)
keyed = False
if key is not None:
keys.append(key[0])
if keyed is True:
try:
fob = server.search(pattern)
except:
fob = None
if fob is not None:
keys.append(fob[0])
else:
pass
else:
pass
for logrus in pattern.split():
try:
key = server.search(hex(int(logrus, 16)))
hexed = True
except ValueError as ve:
key = server.search(logrus)
hexed = False
if key is not None:
keys.append(key[0])
if hexed is True:
try:
fob = server.search(logrus)
except:
fob = None
if fob is not None:
keys.append(fob[0])
else:
pass
else:
pass
if len(keys) > 0:
for key in keys:
import_result = c.key_import(key.key_blob)
results.append(import_result)
for result in results: for result in results:
if result is not None and hasattr(result, "considered") is False: if result is not None and hasattr(result, "considered") is False:

View File

@ -44,18 +44,51 @@ elif len(sys.argv) == 2:
else: else:
pattern = input("Enter the pattern to search for keys or user IDs: ") pattern = input("Enter the pattern to search for keys or user IDs: ")
if pattern is not None: if pattern is not None:
try: try:
key = server.search(hex(int(pattern, 16))) key = server.search(hex(int(pattern, 16)))
except ValueError as e: keyed = True
except ValueError as ve:
key = server.search(pattern) key = server.search(pattern)
keys.append(key[0]) keyed = False
if key is not None:
keys.append(key[0])
if keyed is True:
try:
fob = server.search(pattern)
except:
fob = None
if fob is not None:
keys.append(fob[0])
else:
pass
else:
pass
for logrus in pattern.split(): for logrus in pattern.split():
try: try:
key = server.search(hex(int(logrus, 16))) key = server.search(hex(int(logrus, 16)))
except ValueErrer as ve: hexed = True
except ValueError as ve:
key = server.search(logrus) key = server.search(logrus)
keys.append(key[0]) hexed = False
if key is not None:
keys.append(key[0])
if hexed is True:
try:
fob = server.search(logrus)
except:
fob = None
if fob is not None:
keys.append(fob[0])
else:
pass
else:
pass
if len(keys) > 0: if len(keys) > 0:
for key in keys: for key in keys:
@ -90,4 +123,4 @@ The key IDs for all considered keys were:
print(result.imports[i].fpr) print(result.imports[i].fpr)
print("") print("")
else: else:
pass print("No keys were imported or found.")