Module: Gem::OpenPGP
- Extended by:
- UserInteraction, Shellwords
- Defined in:
- lib/rubygems/openpgp/verification.rb,
lib/rubygems/openpgp/owner_check.rb,
lib/rubygems/openpgp/gpg_helpers.rb,
lib/rubygems/openpgp/keymaster.rb,
lib/rubygems/openpgp/signing.rb,
lib/rubygems/openpgp/options.rb
Defined Under Namespace
Modules: KeyMaster
Class Method Summary collapse
- .check_rubygems_org_owner(gem_name, fingerprint) ⇒ Object
-
.detach_sign(data, key_id = nil, homedir = nil) ⇒ Object
Given a string of data, generate and return a detached signature.
-
.sign_gem(gem, key = nil, homedir = nil) ⇒ Object
Signs an existing gemfile by iterating the tar’ed up contents, and signing any contents.
-
.verify(file_name, data, sig, get_key = false, homedir = nil) ⇒ Object
Given a string containing data, and a string containing a detached signature, verify the data.
- .verify_gem(gem, get_key = false, homedir = nil) ⇒ Object
Class Method Details
.check_rubygems_org_owner(gem_name, fingerprint) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/rubygems/openpgp/owner_check.rb', line 5 def self.check_rubygems_org_owner gem_name, fingerprint uids_and_trust = get_good_uids(fingerprint) owners = Gems.owners(gem_name).map { |o| o["email"] } good_owner_status = find_good_owner(uids_and_trust, owners) if !good_owner_status valid_uids = uids_and_trust.map { |x| x[:uid] } say add_color("Couldn't match good UID against rubygems.org owners!", :red) say add_color("\tGood User Ids: #{pretty_email_list(valid_uids)}", :red) say add_color("\trubygems.org Owners: #{pretty_email_list(owners)}", :red) end good_owner_status rescue Errno::ECONNREFUSED, SocketError => ex say add_color("Can't verify ownership. Couldn't connect with rubygems.org.", :yellow) return false end |
.detach_sign(data, key_id = nil, homedir = nil) ⇒ Object
Given a string of data, generate and return a detached signature. By defualt, this will use your primary secret key. This can be overridden by specifying a key_id for another private key.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/rubygems/openpgp/signing.rb', line 16 def self.detach_sign data, key_id=nil, homedir=nil is_gpg_available is_key_valid key_id if key_id is_homedir_valid homedir if homedir key_flag = "" key_flag = "-u #{shellescape(key_id)}" if key_id homedir_flag = "" homedir_flag = "--homedir #{shellescape(homedir)}" if homedir gpg_args = "#{key_flag} #{homedir_flag} --detach-sign --armor" gpg_results = GPGStatusParser.run_gpg(gpg_args, data) did_gpg_error? gpg_results gpg_results[:stdout] end |
.sign_gem(gem, key = nil, homedir = nil) ⇒ Object
Signs an existing gemfile by iterating the tar’ed up contents, and signing any contents. creating a new file with original contents and OpenPGP sigs. The OpenPGP sigs are saved as .asc files so they won’t conflict with X509 sigs.
Optional param “key” allows you to use a different private key than the GPG default.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/rubygems/openpgp/signing.rb', line 41 def self.sign_gem gem, key=nil, homedir=nil unsigned_gem = gem + ".unsigned" begin FileUtils.mv gem, unsigned_gem rescue Errno::ENOENT => ex raise Gem::CommandLineError, "The gem #{gem} does not seem to exist. (#{ex.})" end unsigned_gem_file = File.open(unsigned_gem, "rb") signed_gem_file = File.open(gem, "wb") signed_gem = Gem::Package::TarWriter.new(signed_gem_file) Gem::Package::TarReader.new(unsigned_gem_file).each do |f| if f.full_name[-4..-1] == ".asc" say("Skipping old OpenPGP signature file #{f.full_name}") next end file_contents = f.read() # Copy file no matter what signed_gem.add_file(f.full_name, 0644) do |outfile| outfile.write(file_contents) end # Only sign if it's really part of the gem and not # a X.509 sig if f.full_name[-3..-1] == ".gz" say add_color("Signing #{f.full_name.inspect}...",:green) signed_gem.add_file(f.full_name + ".asc", 0644) do |outfile| outfile.write(Gem::OpenPGP.detach_sign(file_contents,key,homedir)) end elsif f.full_name[-4..-1] != ".sig" say add_color("Not signing #{f.full_name.inspect}. Didn't expect to see that...",:yellow) end end signed_gem_file.close unsigned_gem_file.close File.delete unsigned_gem_file rescue Exception => ex if unsigned_gem_file FileUtils.mv unsigned_gem_file, gem end raise end |
.verify(file_name, data, sig, get_key = false, homedir = nil) ⇒ Object
Given a string containing data, and a string containing a detached signature, verify the data. If we can’t verify then raise an exception.
Optionally tell gpg to retrive the key if it’s not provided
returns the fingerprint used to sign the file
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/rubygems/openpgp/verification.rb', line 26 def self.verify file_name, data, sig, get_key=false, homedir=nil is_gpg_available is_homedir_valid homedir if homedir data_file = create_tempfile data sig_file = create_tempfile sig get_key_params = "--keyserver pool.sks-keyservers.net --keyserver-options auto-key-retrieve" get_key_params = "" if get_key != true homedir_flags = "" homedir_flags = "--homedir #{homedir}" if homedir gpg_args = "#{get_key_params} #{homedir_flags} --with-colons --verify #{sig_file.path} #{data_file.path}" status_info = {:file_name => file_name} gpg_results = GPGStatusParser.run_gpg(gpg_args) { || verify_extract_status_info(, status_info) } if status_info[:failure] say add_color(status_info[:failure], :red) raise Gem::OpenPGPException, "Fail!" else verify_check_sig status_info end did_gpg_error? gpg_results status_info[:primary_key_fingerprint] end |
.verify_gem(gem, get_key = false, homedir = nil) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/rubygems/openpgp/verification.rb', line 56 def self.verify_gem gem, get_key=false, homedir=nil raise Gem::CommandLineError, "Gem #{gem} not found." if !File.exists?(gem) gem_name = if Gem::VERSION[0..1] == "2." #gotta be a better way Gem::Package.new(gem).spec.name else Gem::Format.from_file_by_path(gem).spec.name end say("Verifying #{gem_name}...") file = File.open(gem,"r") fingerprints = [] tar_files = {} Gem::Package::TarReader.new(file).each do |f| tar_files[f.full_name] = f.read() end tar_files.keys.each do |file_name| next if [".asc",".sig"].include? file_name[-4..-1] if file_name[-3..-1] != ".gz" say add_color("Skipping #{file_name}. Only expected .gz files...", :yellow) next end sig_file_name = file_name + ".asc" if !tar_files.has_key? sig_file_name say add_color("WARNING!!! No sig found for #{file_name}", :red) raise Gem::OpenPGPException, "Can't verify without sig, aborting!!!" end begin fingerprints << Gem::OpenPGP.verify(file_name, tar_files[file_name], tar_files[sig_file_name], get_key, homedir) rescue Gem::OpenPGPException => ex color_code = "31" say add_color(ex., :red) raise end end fingerprints.uniq! # Verify fingerprint and owner fingerprints.each do |fp| verify_gem_check_fingerprint gem_name, fp owner_checks gem_name, fp end ensure file.close unless file.nil? end |