bin/r509 in r509-0.8 vs bin/r509 in r509-0.8.1

- old
+ new

@@ -1,17 +1,38 @@ #!/usr/bin/ruby require 'rubygems' require 'r509' require 'r509/version' require 'openssl' +require 'trollop' -subject = OpenSSL::X509::Name.new -selfsign = 0 -if ARGV[0].nil? then - puts "Interactive CSR generation using r509 v#{R509::VERSION}." - puts "" - puts "You can also call with 1-3 args (string subject, int bit_strength, [optional days selfsign length])" +opts = Trollop::options do + opt :interactive, "Interactive CSR/self-signed certificate generation. Overrides all flags other than keyout and out." + opt :subject, "X509 subject / delimited. Example: /CN=test.com/O=Org/C=US/ST=Illinois/L=Chicago", :type => :string + opt :message_digest, "Message digest to use. sha1, sha256, sha512, md5", :type => :string, :default => 'sha1' + opt :duration, "Self-sign the certificate with the duration (in days) specified.", :type => :integer + opt :bits, "Bit length of generated key.", :type => :integer, :default => 2048 + opt :keyout, "File name to save generated key.", :type => :string + opt :out, "File name to save generated CSR or self-signed certificate", :type => :string + version "r509 #{R509::VERSION}" +end + +if opts[:interactive] == true or opts[:subject].nil? then + print "CSR Bit Strength (2048):" + bit_strength = gets.chomp + bit_strength = (bit_strength.to_i > 0)? bit_strength.to_i : 2048 + + print "Message Digest (sha1):" + md = gets.chomp + md = case md + when 'sha1' then 'sha1' + when 'sha256' then 'sha256' + when 'sha512' then 'sha512' + when 'md5' then 'md5' + else 'sha1' + end + subject = [] print "C (US): " c = gets.chomp c = c.empty? ? 'US':c; subject.push ['C',c] @@ -40,48 +61,74 @@ print "CN: " subject.push ['CN',gets.chomp] print "SAN Domains (comma separated):" san_domains = [] san_domains = gets.chomp.split(',').collect { |domain| domain.strip } - csr = R509::Csr.new(:subject => subject, :bit_strength => 2048, :san_names => san_domains) + csr = R509::Csr.new( + :subject => subject, + :bit_strength => bit_strength, + :san_names => san_domains, + :message_digest => md + ) + + selfsign = 0 print "Self-signed cert duration in days (null disables self-sign):" selfsign_input = gets.chomp if selfsign_input.to_i > 0 selfsign = selfsign_input.to_i end - - -else - ARGV[0].split('/').each { |item| +elsif not opts[:subject].nil? + subject = OpenSSL::X509::Name.new + opts[:subject].chomp.split('/').each { |item| if item != '' then value = item.split('=') subject.add_entry(value[0],value[1]) end } - bit_strength = nil - if ARGV.size > 1 then - bit_strength = ARGV[1].to_i - else - bit_strength = 2048 - end - if ARGV.size > 2 and ARGV[2].to_i > 0 - selfsign = ARGV[2].to_i - end - csr = R509::Csr.new(:subject => subject, :bit_strength => bit_strength) + bit_strength = opts[:bits] + csr = R509::Csr.new( + :subject => subject, + :bit_strength => bit_strength, + :message_digest => opts[:message_digest] + ) + selfsign = opts[:duration] || 0 end if selfsign > 0 ca = R509::CertificateAuthority::Signer.new - cert = ca.selfsign(:csr => csr, :not_after => Time.now.to_i+86400*selfsign) - puts csr.key.to_pem - puts cert + cert = ca.selfsign( + :csr => csr, + :not_after => Time.now.to_i+86400*selfsign, + :message_digest => opts[:message_digest] + ) + if opts[:keyout].nil? + puts csr.key.to_pem + else + File.open(opts[:keyout], 'w') {|f| f.write(csr.key.to_pem) } + end + if opts[:out].nil? + puts cert.to_pem + else + File.open(opts[:out], 'w') {|f| f.write(cert.to_pem) } + end + puts cert.subject if not cert.san_names.empty? puts "SAN(s): "+cert.san_names.join(", ") end else - puts csr.key.to_pem - puts csr + if opts[:keyout].nil? + puts csr.key.to_pem + else + File.open(opts[:keyout], 'w') {|f| f.write(csr.key.to_pem) } + end + + if opts[:out].nil? + puts csr.to_pem + else + File.open(opts[:out], 'w') {|f| f.write(csr.to_pem) } + end + puts csr.subject if not csr.san_names.empty? puts "SAN(s): "+csr.san_names.join(", ") end end