124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
# File 'lib/universa/keytool/keytool.rb', line 124
def init_parser
opt_parser = OptionParser.new { |opts|
opts.banner = ANSI.bold { "\nUniversa Key tool #{Universa::VERSION}" }
opts.separator ""
opts.on("--no-password",
"create resources not protected by password. Not recommended.") { |x|
@require_password = x
}
opts.on("-a", "--autogenerate_password",
"the new secure password will be generated and shown on the console",
"while the password is safe, printing it out to the console may not.",
"Normally, system promts the password on the console that is",
"more secure") { |x|
@autogenerate_password = x
}
opts.on("-o FILE", "--output FILE", "file name for the output file") { |f|
@output_file = f
}
opts.on("-F", "--force", "force overwrite file") {
@overwrite = true
}
opts.on("-g SIZE", "--generate SIZE", "generate new private key of the specified bis size") { |s|
task {
strength = s.to_i
case strength
when 2048, 4096
task {
output = output_file(".private.unikey")
check_overwrite(output)
key = PrivateKey.new(strength)
save_key(output, key)
puts "\nNew private key is generated: #{output}"
}
else
error "Only supported key sizes are 2048, 4096"
end
}
}
opts.on("-u FILE", "--update FILE", "update password on the existing key (also add/remove",
"requires -o output_file or --overwrite to change it in place") { |name|
task {
output = output_file(".private.unikey", name)
check_overwrite output
key = load_key(name)
puts("\rKey loaded OK ")
save_key output, key
}
}
opts.on("-r ROUNDS", "--rounds ROUNDS", "how many PBKDF2 rounds to use when saving with password",
"(1 million by default, the more the better, but takes time)") { |r|
@rounds = human_to_i(r)
@rounds < 100000 and error "To few rounds, use at least 100000"
}
opts.on("-p FILE", "--public FILE", "extract public key. If output file is not specified,",
"prints as universa text object to the standard output") { |name|
task {
key = load_key(name, true)
if @output_file
open(output_file(".public.unikey"), 'wb') { |f| f << key.pack() }
else
puts format_text_object(key.pack(), "public key", fileName: name)
end
}
}
opts.on("-s FILE", "--show FILE", "show key information") { |name|
task {
key = load_key(name, true)
is_private = key.is_a? PrivateKey
puts "\r----------------------------------------------------------------------------------------"
puts "#{is_private ? 'Private' : 'Public'} key, #{key.info.getKeyLength() * 8} bits\n"
puts "Short address : #{ANSI.bold { key.short_address.to_s }}"
puts "Long address : #{ANSI.bold { key.long_address.to_s }}"
}
}
opts.separator ""
def sample(text)
" " + ANSI.bold { ANSI.green { text } }
end
opts.on_tail("-h", "--help", "Show this message") do
puts opts
puts <<-End
#{ANSI.bold { "Usage samples:" }}
Generate new key 'foo.private.unikey' - will ask password from console (notice extension will be added automatically)
#{sample "unikeys -g 2048 -o foo"}
Show foo addresses:
#{sample "unikeys -s foo.private.unikey"}
Change password of the foo key and save it into new file bar.private.unikey (keeping both for security), will ask
new password from console
#{sample "unikeys -u foo.private.unikey -o bar"}
Change password in place (overwriting old file)
#{sample "unikeys -u foo.private.unikey -f"}
See project home page at #{ANSI.underline { "https://github.com/sergeych/universa" }}
End
exit
end
opts.on_tail("-v", "--version", "Show versions") do
puts "Universa core version: #{Service.umi.core_version}"
puts "UMI version : #{Service.umi.version}"
client = Universa::Client.new
puts "Connected nodes : #{client.size}"
exit
end
}
begin
opt_parser.order!
if @tasks.empty?
puts "nothing to do. Please specify one of: -g, -s or -u. See help for more (-h)."
else
@tasks.each { |t| t.call }
end
rescue MessageException, OptionParser::ParseError => e
STDERR.puts ANSI.red { ANSI.bold { "\nError: #{e}\n" } }
exit(1000)
rescue Interrupt
exit(1010)
rescue
STDERR.puts ANSI.red { "\n#{$!.backtrace.reverse.join("\n")}\n" }
STDERR.puts ANSI.red { ANSI.bold { "Error: #$! (#{$!.class.name})" } }
exit(2000)
end
end
|