# File rubygems/commands/cert_command.rb, line 7
def initialize
super 'cert', 'Manage RubyGems certificates and signing settings',
:add => [], :remove => [], :list => [], :build => [], :sign => []
OptionParser.accept OpenSSL::X509::Certificate do |certificate|
begin
OpenSSL::X509::Certificate.new File.read certificate
rescue Errno::ENOENT
raise OptionParser::InvalidArgument, "#{certificate}: does not exist"
rescue OpenSSL::X509::CertificateError
raise OptionParser::InvalidArgument,
"#{certificate}: invalid X509 certificate"
end
end
OptionParser.accept OpenSSL::PKey::RSA do |key_file|
begin
key = OpenSSL::PKey::RSA.new File.read key_file
rescue Errno::ENOENT
raise OptionParser::InvalidArgument, "#{key_file}: does not exist"
rescue OpenSSL::PKey::RSAError
raise OptionParser::InvalidArgument, "#{key_file}: invalid RSA key"
end
raise OptionParser::InvalidArgument,
"#{key_file}: private key not found" unless key.private?
key
end
add_option('-a', '--add CERT', OpenSSL::X509::Certificate,
'Add a trusted certificate.') do |cert, options|
options[:add] << cert
end
add_option('-l', '--list [FILTER]',
'List trusted certificates where the',
'subject contains FILTER') do |filter, options|
filter ||= ''
options[:list] << filter
end
add_option('-r', '--remove FILTER',
'Remove trusted certificates where the',
'subject contains FILTER') do |filter, options|
options[:remove] << filter
end
add_option('-b', '--build EMAIL_ADDR',
'Build private key and self-signed',
'certificate for EMAIL_ADDR') do |email_address, options|
options[:build] << email_address
end
add_option('-C', '--certificate CERT', OpenSSL::X509::Certificate,
'Signing certificate for --sign') do |cert, options|
options[:issuer_cert] = cert
end
add_option('-K', '--private-key KEY', OpenSSL::PKey::RSA,
'Key for --sign or --build') do |key, options|
options[:key] = key
end
add_option('-s', '--sign CERT',
'Signs CERT with the key from -K',
'and the certificate from -C') do |cert_file, options|
raise OptionParser::InvalidArgument, "#{cert_file}: does not exist" unless
File.file? cert_file
options[:sign] << cert_file
end
end
# File rubygems/commands/cert_command.rb, line 117
def build name
key = options[:key] || Gem::Security.create_key
cert = Gem::Security.create_cert_email name, key
key_path = Gem::Security.write key, "gem-private_key.pem"
cert_path = Gem::Security.write cert, "gem-public_cert.pem"
say "Certificate: #{cert_path}"
say "Private Key: #{key_path}"
say "Don't forget to move the key file to somewhere private!"
end
# File rubygems/commands/cert_command.rb, line 130
def certificates_matching filter
return enum_for __method__, filter unless block_given?
Gem::Security.trusted_certificates.select do |certificate, _|
subject = certificate.subject.to_s
subject.downcase.index filter
end.sort_by do |certificate, _|
certificate.subject.to_a.map { |name, data,| [name, data] }
end.each do |certificate, path|
yield certificate, path
end
end
# File rubygems/commands/cert_command.rb, line 82
def execute
options[:add].each do |certificate|
Gem::Security.trust_dir.trust_cert certificate
say "Added '#{certificate.subject}'"
end
options[:remove].each do |filter|
certificates_matching filter do |certificate, path|
FileUtils.rm path
say "Removed '#{certificate.subject}'"
end
end
options[:list].each do |filter|
certificates_matching filter do |certificate, _|
# this could probably be formatted more gracefully
say certificate.subject.to_s
end
end
options[:build].each do |name|
build name
end
unless options[:sign].empty? then
load_default_cert unless options[:issuer_cert]
load_default_key unless options[:key]
end
options[:sign].each do |cert_file|
sign cert_file
end
end
# File rubygems/commands/cert_command.rb, line 182
def load_default_cert
cert_file = File.join Gem.user_home, 'gem-public_cert.pem'
cert = File.read cert_file
options[:issuer_cert] = OpenSSL::X509::Certificate.new cert
rescue Errno::ENOENT
alert_error "--certificate not specified and ~/.gem/gem-public_cert.pem does not exist"
terminate_interaction 1
rescue OpenSSL::X509::CertificateError
alert_error "--certificate not specified and ~/.gem/gem-public_cert.pem is not valid"
terminate_interaction 1
end
# File rubygems/commands/cert_command.rb, line 198
def load_default_key
key_file = File.join Gem.user_home, 'gem-private_key.pem'
key = File.read key_file
options[:key] = OpenSSL::PKey::RSA.new key
rescue Errno::ENOENT
alert_error "--private-key not specified and ~/.gem/gem-private_key.pem does not exist"
terminate_interaction 1
rescue OpenSSL::PKey::RSAError
alert_error "--private-key not specified and ~/.gem/gem-private_key.pem is not valid"
terminate_interaction 1
end
# File rubygems/commands/cert_command.rb, line 214
def sign cert_file
cert = File.read cert_file
cert = OpenSSL::X509::Certificate.new cert
permissions = File.stat(cert_file).mode & 0777
issuer_cert = options[:issuer_cert]
issuer_key = options[:key]
cert = Gem::Security.sign cert, issuer_key, issuer_cert
Gem::Security.write cert, cert_file, permissions
end
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please see Improve the docs, or visit Documenting-ruby.org.