X-Git-Url: http://git.draconx.ca/gitweb/homepage.git/blobdiff_plain/fe387389cf437d11a969d51b5625cd6bc4ddb79f..220aba7ec291f6f8de8982074a3488d28b4aee1f:/lib/gpg-wkd.rb diff --git a/lib/gpg-wkd.rb b/lib/gpg-wkd.rb index c6e5fcc..b2379f1 100644 --- a/lib/gpg-wkd.rb +++ b/lib/gpg-wkd.rb @@ -1,4 +1,5 @@ -# Nick's web site: Export public keys for the Web Key Directory +# Nick's web site: Export GPG public keys for HTTP Keyserver and the +# Web Key Directory # # Copyright © 2022 Nick Bowler # @@ -26,13 +27,47 @@ module WKD def WKD.wksclient; @@wksclient end def WKD.wksclient=(x); @@wksclient = x end - # Return a list list of all UIDs known from the given GPG keyrings. + # Convert a list of keyring filenames into GPG keyring arguments + def WKD.keyring_args(args) + return [ "--no-default-keyring", + *args.map { |x| "--keyring=" + (x['/'] ? x : "./" + x) } ] + end + + # Helper for implementing export filters below + def WKD.export(item, id, *args) + data, result = Open3.capture2(@@gpg2, "--export", *args, + *WKD.keyring_args(item[:keyrings]), id.chomp) + raise "gpg failed" unless result.success? + return data + end + + # Return a list of all key fingerprints known from the given GPG keyrings. + def WKD.keys_from_keyrings(*args) + fps = {} + + Open3.popen2(@@gpg2, + "--with-colons", "--list-keys", *WKD.keyring_args(args) + ) do |stdin, stdout, result| + stdin.close + stdout.each do |line| + fields = line.split(":") + next if fields[0] != "fpr" + fps[fields[9]] = true + end + stdout.close + + raise "gpg failed" unless result.value.success? + end + + return fps.keys + end + + # Return a list of all UIDs known from the given GPG keyrings. def WKD.uids_from_keyrings(*args) uids = {} Open3.popen2(@@gpg2, - "--no-default-keyring", "--with-colons", "--list-keys", - *args.map { |x| "--keyring=" + (x['/'] ? x : "./" + x) } + "--with-colons", "--list-keys", *WKD.keyring_args(args) ) do |stdin, stdout, result| stdin.close stdout.each do |line| @@ -112,20 +147,50 @@ def create_wkd_items(keyring_items) end end +def create_hkp_items(keyring_items) + keyring_files = {} + [*keyring_items].each { |item| keyring_files[item.raw_filename] = true } + + fps = WKD.keys_from_keyrings(*keyring_files.keys) + keyids_64 = {} + keyids_32 = {} + + fps.each do |fp| + id64 = fp[-16..] + id32 = fp[-8..] + + keyids_64[id64] = keyids_64[id64].to_i + 1 + keyids_32[id32] = keyids_32[id32].to_i + 1 + end + + fps.each do |fp| + id64 = fp[-16..] + id32 = fp[-8..] + + attrs = { keyrings: keyring_files.keys } + attrs[:id64] = id64 if keyids_64[id64] == 1 + attrs[:id32] = id32 if keyids_32[id32] == 1 + + @items.create("0x"+fp, attrs, "/gpg/" + fp) + end +end + # Convert items created by create_wkd_items into real GPG keyrings. class WKDExport < Nanoc::Filter identifier :wkd_export type :text => :binary def run(content, params = {}) - args = @item[:keyrings].map { |x| - "--keyring=" + (x['/'] ? x : "./" + x) - }; - args.append("--armor") if params[:armor] - - dummy, result = Open3.capture2(WKD.gpg2, "--export", - "--no-default-keyring", "--output=" + output_filename, - *args, content.chomp) - raise "gpg failed" unless result.success? + WKD.export(item, content, "--output=" + output_filename) + end +end + +class WKDExportArmor < Nanoc::Filter + identifier :wkd_export_armor + type :text + + def run(content, params = {}) + data = WKD.export(item, content, "--armor") + return data end end