Skip to content

Instantly share code, notes, and snippets.

@TruncatedDinoSour
Last active August 21, 2024 08:45
Show Gist options
  • Save TruncatedDinoSour/a0874bf1e90647a9a49985e531d9d15f to your computer and use it in GitHub Desktop.
Save TruncatedDinoSour/a0874bf1e90647a9a49985e531d9d15f to your computer and use it in GitHub Desktop.
OPENPGPKEY DNS record generator implementing RFC 7929 (https://www.rfc-editor.org/rfc/rfc7929.txt)
#!/usr/bin/env sh
# OPENPGPKEY DNS record generator implementing RFC 7929 (https://www.rfc-editor.org/rfc/rfc7929.txt)
#
# NOT IMPLEMENTED:
#
# 2. The local-part is first canonicalized using the following rules.
# If the local-part is unquoted, any comments and/or folding
# whitespace (CFWS) around dots (".") is removed. Any enclosing
# double quotes are removed. Any literal quoting is removed.
#
# 3. If the local-part contains any non-ASCII characters, it SHOULD be
# normalized using the Unicode Normalization Form C from
# [Unicode90]. Recommended normalization rules can be found in
# Section 10.1 of [RFC6530].
#
# Author: Arija A. (Ari Archer) <ari@ari.lt>
#
# License: OPENPGPKEY DNS record generator by Arija A. is marked with CC0 1.0 Universal
# See the license text at https://creativecommons.org/publicdomain/zero/1.0/
# This work is released for the public domain.
set -eu
main() {
if [ "$#" -ne 2 ]; then
{
echo "Generates an OPENPGPKEY DNS record based off your Email and a Public GPG key ID."
echo "Usage: $0 <email> <GPG key ID>"
} >&2
return 1
fi
# Confirm user localpart
localpart="$(printf -- '%s' "$1" | cut -d'@' -f1 | tr '[:upper:]' '[:lower:]')"
printf -- " * Your email username (localpart) is '\033[1m%s\033[0m', correct? In lowercase, enter either 'y' (for yes) or 'n' (for no): " "$localpart"
read -r yn
if [ "$yn" -ne 'y' ]; then
echo " * Incorrect information provided." >&2
return 1
fi
# Localpart digest is the SHA256 hex digest truncated to 28 octets (which is 56 hex bytes 0x??)
localpart_digest="$(printf -- '%s' "$localpart" | sha256sum | cut -d' ' -f1 | cut -c1-56)"
# And the value has to be the base64-encoded public key, exported as binary
gpg_public_key_b64="$(gpg --export --export-options export-minimal,no-export-attributes -- "$2" | base64 -w 0)"
printf '\n\033[32m%s\033[0m._openpgpkey. \033[90mIN OPENPGPKEY\033[0m \033[1m%s\033[0m\n' "$localpart_digest" "$gpg_public_key_b64"
}
main "$@"
@TruncatedDinoSour
Copy link
Author

The original version of this script truncated the hex hash digest, rather than the hex digest: this is wrong. My interpretation of this RFC was wrong originally, and I have put in my efforts to correct this script as well as the blog post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment