python: HKP search and import updates
authorBen McGinnes <ben@adversary.org>
Mon, 10 Dec 2018 20:14:28 +0000 (07:14 +1100)
committerBen McGinnes <ben@adversary.org>
Mon, 10 Dec 2018 20:14:28 +0000 (07:14 +1100)
* 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.

lang/python/doc/rst/gpgme-python-howto.rst
lang/python/doc/src/gpgme-python-howto
lang/python/doc/texinfo/gpgme-python-howto.texi
lang/python/examples/howto/import-keys-hkp.py

index 1bd069c..7843965 100644 (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
 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:
 
 Working with ProtonMail
@@ -1068,6 +1076,7 @@ the keys found.
    c = gpg.Context()
    server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
    results = []
+   keys = []
 
    if len(sys.argv) > 2:
        pattern = " ".join(sys.argv[1:])
@@ -1076,22 +1085,56 @@ the keys found.
    else:
        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 = []
+
+   if pattern is not None:
+       try:
+           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():
-           if logrus.startswith("0x") is True:
+           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:
-               key = server.search("0x{0}".format(logrus))
-           keys.append(key[0])
-       print("Found {0} key(s).".format(len(keys)))
+               pass
 
-   for key in keys:
-       import_result = c.key_import(key.key_blob)
-       results.append(import_result)
+
+   if len(keys) > 0:
+       for key in keys:
+           import_result = c.key_import(key.key_blob)
+           results.append(import_result)
 
    for result in results:
        if result is not None and hasattr(result, "considered") is False:
index 9820d86..0c1239b 100644 (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
 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
     :PROPERTIES:
@@ -1097,6 +1105,7 @@ import sys
 c = gpg.Context()
 server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
 results = []
+keys = []
 
 if len(sys.argv) > 2:
     pattern = " ".join(sys.argv[1:])
@@ -1105,22 +1114,56 @@ elif len(sys.argv) == 2:
 else:
     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 = []
+
+if pattern is not None:
+    try:
+        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():
-        if logrus.startswith("0x") is True:
+        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:
-            key = server.search("0x{0}".format(logrus))
-        keys.append(key[0])
-    print("Found {0} key(s).".format(len(keys)))
+            pass
 
-for key in keys:
-    import_result = c.key_import(key.key_blob)
-    results.append(import_result)
+
+if len(keys) > 0:
+    for key in keys:
+        import_result = c.key_import(key.key_blob)
+        results.append(import_result)
 
 for result in results:
     if result is not None and hasattr(result, "considered") is False:
index 420ea7d..552ef91 100644 (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
 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
 * Working with ProtonMail::
 * Importing with HKP for Python::
@@ -1268,6 +1276,7 @@ import sys
 c = gpg.Context()
 server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
 results = []
+keys = []
 
 if len(sys.argv) > 2:
     pattern = " ".join(sys.argv[1:])
@@ -1276,22 +1285,56 @@ elif len(sys.argv) == 2:
 else:
     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 = []
+
+if pattern is not None:
+    try:
+        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():
-        if logrus.startswith("0x") is True:
+        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:
-            key = server.search("0x@{0@}".format(logrus))
-        keys.append(key[0])
-    print("Found @{0@} key(s).".format(len(keys)))
+            pass
 
-for key in keys:
-    import_result = c.key_import(key.key_blob)
-    results.append(import_result)
+
+if len(keys) > 0:
+    for key in keys:
+        import_result = c.key_import(key.key_blob)
+        results.append(import_result)
 
 for result in results:
     if result is not None and hasattr(result, "considered") is False:
index 832a888..1abd0fd 100755 (executable)
@@ -44,18 +44,51 @@ elif len(sys.argv) == 2:
 else:
     pattern = input("Enter the pattern to search for keys or user IDs: ")
 
+
 if pattern is not None:
     try:
         key = server.search(hex(int(pattern, 16)))
-    except ValueError as e:
+        keyed = True
+    except ValueError as ve:
         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():
         try:
             key = server.search(hex(int(logrus, 16)))
-        except ValueErrer as ve:
+            hexed = True
+        except ValueError as ve:
             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:
     for key in keys:
@@ -90,4 +123,4 @@ The key IDs for all considered keys were:
             print(result.imports[i].fpr)
         print("")
     else:
-        pass
+        print("No keys were imported or found.")