require "gdbm" require "openssl" require "optparse" $digest = OpenSSL::Digest::SHA256.new $opts = Array.new $args = Hash.new op = OptionParser.new { |opts| opts.banner = "Usage: #{__FILE__} [OPTIONS]" opts.on("--show-public", "Show public key") { |arg| $opts.push :pub } opts.on("--show-private", "Show private key") { |arg| $opts.push :priv } opts.on("--show-only", "Show only keys") { |arg| $opts.push :showonly } opts.on("-n", "--name NAME", "Name of the file that contains or should contain the signature and the data") { |arg| $args[:name] = arg } opts.on("-d", "--data DATA", "The data to be saved and signed.") { |arg| $args[:data] = arg } opts.on("-f", "--file FILE", "The file that contains the key") { |arg| $fn = arg } opts.on("-p", "--pack", "Pack data") { |arg| $opts.push :pack } opts.on("-u", "--unpack", "Unpack data") { |arg| $opts.push :unpack } opts.on("-s", "--key-strength STRENGTH", "Unpack data") { |arg| $args[:keystr] = arg } opts.on("-c", "--create", "Create key") { |arg| $opts.push :create } opts.on("-e", "--extract-public", "Save the public key in a separate file") { |arg| $opts.push :extract } opts.on("--extract-from-i2prm", "Extract private key from i2prm database") { |arg| $opts.push :i2prm } opts.on("-h", "--help", "Prints this help") { puts "OpenSSL RSA key manager" puts "=======================\n\n" puts opts puts "Examples:" puts " Create a new key: ruby #{__FILE__} --create --key-strength 512 -f key.rsa" puts " Extract public key: ruby #{__FILE__} --extract-public -n pub.rsa -f key.rsa" puts " Pack data: ruby #{__FILE__} --pack --name result --data \"Hello World!\" -f key.rsa" puts " Unpack data: ruby #{__FILE__} --unpack --name result -f pub.rsa" puts " Extract key from i2prm database: ruby #{__FILE__} --extract-from-i2prm -f key.rsa -n i2prm.gdbm" exit } } op.parse! #pp $opts #pp $args def packdata name, data db = GDBM.new name db["data"] = data db["sign"] = $key.sign $digest, data db.close end def unpackdata name db = GDBM.new name puts "*#{db["data"]}*." puts "#{$key.verify($digest, db["sign"], db["data"]) ? "Valid" : "Invalid"} signature." db.close end def defaultoptions if $fn == nil puts "Require filename" exit end $key = OpenSSL::PKey::RSA.new File.read $fn if $opts.include? :pub puts $key.public_key.to_s end if $opts.include? :priv puts $key.to_s end end if $opts.include? :create if $args[:keystr] == nil puts "Require key strength" exit elsif $args[:keystr].to_i < 512 puts "key strength must be over 512 bytes" exit elsif $fn == nil puts "Require filename" exit end $key = OpenSSL::PKey::RSA.new $args[:keystr].to_i File.write $fn, $key.to_s elsif $opts.include? :showonly defaultoptions elsif $opts.include? :pack defaultoptions if $args[:name] == nil puts "Require target filename" exit elsif $args[:data] == nil puts "Require data" exit end packdata $args[:name], $args[:data] elsif $opts.include? :unpack defaultoptions if $args[:name] == nil puts "Require target filename" exit end unpackdata $args[:name] elsif $opts.include? :extract defaultoptions if $args[:name] == nil puts "Require target filename" exit end File.write $args[:name], $key.public_key.to_s elsif $opts.include? :i2prm if $fn == nil puts "Require filename" exit end if $args[:name] == nil puts "Require target filename" exit end i2prm = GDBM.new $args[:name], 0555, GDBM::READER File.write $fn, i2prm["keypair-privkey"].chars.map { |c| c == "|" ? "\n" : c }.join i2prm.close end