#-- # Copyright (C) 2018 Wolfgang Hotwagner # # This file is part of the cryptorecord gem # # This cryptorecord gem is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This cryptorecord gem is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this cryptorecord gem; if not, write to the # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, # Boston, MA 02110-1301 USA #++ # This module provides the api for cryptorecords module Cryptorecord require 'openssl' require 'mail' # Cryptorecord::Openpgpkey-class generates # openphpkeys-dns-records. Instances must have an # uid. The PGP-Key can be read from file # @!attribute [r] uid # @return [Mail::Address] the userid or nil # @!attribute [r] key # @return [String] the pgp-key as a string # @!attribute [r] rectype # @return [String] "OPENPGPKEY" class Openpgpkey attr_reader :uid, :key, :rectype # This constructor initializes uid and key by calling the setters. # @see uid= # # @param [Hash] args the options to initialize the object with # @option args [String] uid email-address associated with the pgp-key # @option args [String] key pgp-key def initialize(args = {}) self.uid = args.fetch(:uid, nil) self.key = args.fetch(:key, nil) @rectype = 'OPENPGPKEY' end # This setter takes the argument val to create a Mail::Address-object. # The argument val can be a email-address-string or a Mail::Address-object. # Make sure this is the proper uid for the pgp-key! # # @param [String|Mail::Address] val The email-address without brackets # @raise Cryptorecord::ArgumentError def uid=(val) if val.nil? @uid = nil return end case val when String @uid = Mail::Address.new("<#{val}>") when Mail::Address @uid = Mail::Address.new("<#{val.address}>") else raise Cryptorecord::ArgumentError, "Unsupported datatype #{val.class} for val" end end # This getter returns the SHA256sum of the # uid-local-part(email-address) as defined # in rfc7929 # # @return [String] the local-part of the keys # uid(email-address) as SHA256 reduced to 56bytes or nil def localpart @uid.nil? ? nil : OpenSSL::Digest::SHA256.new(@uid.local.to_s).to_s[0..55] end # This getter returns the domain-part of the uid(email-address) or nil # # @return [String] domain the domain-part of the keys uid(email-address) def domain @uid.nil? ? nil : @uid.domain end # This method sets the pgp-key. It takes the public-key-block # and trims the header, blankline and checksum # # @param [String] val PGP-Public-Key-Block(ASCII Armor) # as defined in rfc4880 section 6.2 def key=(val) return if val.nil? @key = '' val.split(/\n/).each do |x| @key += trimpgpkey(x).to_s end @key = @key.gsub(/=.{4}$/, '') end # This method reads the pgp-key from a given file # # @param [String] keyfile Path to the keyfile # @raise Cryptorecord::ArgumentError def read_file(keyfile) raise Cryptorecord::ArgumentError, 'No keyfile defined' if keyfile.nil? data = File.read(keyfile) self.key = data end # This method returns the left-hand name of a dns-record # @return [String] left-hand name of a dns-record def left "#{localpart}._openpgpkey.#{domain}." end # This method returns the right-hand content of a dns-record # @return [String] right-hand content of a dns-record def right @key.to_s end # This method concats the openpgpkey-record # # @return [String] openpgpkey dns-record as defined in rfc7929 def to_s "#{left} IN #{@rectype} #{right}" end private # This function trims the pgpkey so that all headers, footers, # blanklines, and stuff # are gone # # @param [String] val onne line of the pgpkey-block # # @return An empty string if something has to be trimmed, # otherwise the line itself def trimpgpkey(val) case val when '-----BEGIN PGP PUBLIC KEY BLOCK-----' '' when '-----END PGP PUBLIC KEY BLOCK-----' '' when /^\s*\n$/ '' else val.to_s end end end end