Skip to content

Instantly share code, notes, and snippets.

@gwire
Last active July 16, 2022 20:44
Show Gist options
  • Save gwire/936763e6990919598f494977ec4d6831 to your computer and use it in GitHub Desktop.
Save gwire/936763e6990919598f494977ec4d6831 to your computer and use it in GitHub Desktop.
Script to generate OpenPGP Web Key Directory URLs
#!/usr/bin/env python
# wks-id.py - Generate an OpenPGP Web Key Directory URL for an email address
#
# example: echo "Example <[email protected]>" | ./wks-url.py -a
# returns: https://openpgpkey.example.org/.well-known/openpgpkey/example.org/hu/iy9q119eutrkn8s1mk4r39qejnbu3n5q?l=Joe.Doe
#
### See https://tools.ietf.org/html/draft-koch-openpgp-webkey-service-07
#
# 2019 github.com/gwire
#
## python's base64 module doesn't support z-base-32 so you'll need to install an unmaintained module
## pip install zbase32
import sys
import argparse
from hashlib import sha1
from email.utils import parseaddr
from urllib import quote
import zbase32
parser = argparse.ArgumentParser(description='Generate an OpenPGP Web Key Directory URL for an email address.',
epilog="Local parts without domains will just return the 32 octet string. See https://tools.ietf.org/html/draft-koch-openpgp-webkey-service-07")
parser.add_argument('email', metavar='email', type=str, nargs="?", help='email address')
group = parser.add_mutually_exclusive_group()
group.add_argument("-a", "--advanced", help="output advanced url (default)", action="store_true")
group.add_argument("-d", "--direct", help="output direct url", action="store_true")
group.add_argument("-i", "--id", help="output id", action="store_true")
def genLocalHash( localpart ):
lh = sha1(localpart.lower())
return zbase32.b2a(lh.digest())
def genAdvancedUrl(localpart,domain):
return("https://openpgpkey." + domain.lower() + "/.well-known/openpgpkey/" + domain.lower() + "/hu/" + genLocalHash(localpart) + "?l=" + quote(localpart))
def genDirectUrl(localpart,domain):
return("https://" + domain.lower() + "/.well-known/openpgpkey/hu/" + genLocalHash(localpart) + "?l=" + quote(localpart))
def genId(localpart,domain):
return(genLocalHash(localpart) + "@" + domain.lower())
args = parser.parse_args()
if args.email:
email_str = "".join(args.email)
else:
email_str = "".join(sys.stdin).strip("\n")
actual_email = parseaddr(email_str)[1]
localpart = actual_email.split("@")[0]
if len(actual_email.split("@")) > 1:
domain = actual_email.split("@")[1]
else:
domain = "invalid"
if domain == "invalid":
print genLocalHash(localpart)
elif args.id:
print genId(localpart,domain)
elif args.direct:
print genDirectUrl(localpart,domain)
else:
print genAdvancedUrl(localpart,domain)
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment