pkernel_jce 0.3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,5 @@
1
1
 
2
2
 
3
-
4
-
5
3
  require 'pkernel'
6
4
  require_relative 'csr'
7
5
  require_relative 'global'
@@ -1,7 +1,11 @@
1
1
 
2
2
 
3
3
  module PkernelJce
4
+ #
5
+ # Common converter between different format
6
+ #
4
7
  module Converter
8
+
5
9
  def to_hex(bin)
6
10
  String.from_java_bytes(org.bouncycastle.util.encoders.Hex.encode(bin))
7
11
  end
@@ -21,9 +25,26 @@ module PkernelJce
21
25
  java.util.Base64.decoder.decode(str)
22
26
  end
23
27
  # end from_b64
28
+
29
+ #
30
+ # Convert to MimeEncoder base64 format which limit per line 80 characters
31
+ #
32
+ def to_mb64(bin)
33
+ String.from_java_bytes(java.util.Base64.getMimeEncoder.encode(bin))
34
+ end
35
+ # end to_mb64
36
+
37
+ #
38
+ # Convert from MimeEncoder base64 format
39
+ #
40
+ def from_mb64(str)
41
+ java.util.Base64.getMimeDecoder.decode(str)
42
+ end
43
+ # end from_mb64
24
44
 
25
45
  end
26
46
  # module Converter
27
47
  #
48
+
28
49
  end
29
50
  # module PkernelJce
File without changes
@@ -71,6 +71,18 @@ module PkernelJce
71
71
  end
72
72
  # end dump
73
73
 
74
+ def dump_to_file(csr, file, opts = { })
75
+ opts = { } if opts.nil?
76
+ raise PkernelJce::Error, "Option to dump CSR to file should be a hash" if not opts.is_a?(Hash)
77
+ dump(csr, opts.merge({ file: file }))
78
+ end
79
+
80
+ def dump_to_mem(csr, opts = { })
81
+ opts = { } if opts.nil?
82
+ raise PkernelJce::Error, "Option to dump CSR to memory should be a hash" if not opts.is_a?(Hash)
83
+ dump(csr, opts)
84
+ end
85
+
74
86
 
75
87
  def load(options = {})
76
88
  #todo is this content pem or binary?
@@ -98,6 +110,18 @@ module PkernelJce
98
110
  end
99
111
  # end load
100
112
 
113
+ def load_from_file(file, opts = { })
114
+ opts = { } if opts.nil?
115
+ raise PkernelJce::Error, "Option to load CSR from file should be a hash" if not opts.is_a?(Hash)
116
+ load(opts.merge({ file: file }))
117
+ end
118
+
119
+ def load_from_mem(bin, opts = { })
120
+ opts = { } if opts.nil?
121
+ raise PkernelJce::Error, "Option to load CSR from bin should be a hash" if not opts.is_a?(Hash)
122
+ load(opts.merge({ bin: bin }))
123
+ end
124
+
101
125
  def is_signature_valid?(csr)
102
126
  cvProv = org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder.new.build(csr.getSubjectPublicKeyInfo)
103
127
  csr.isSignatureValid(cvProv)
File without changes
@@ -8,7 +8,11 @@ module PkernelJce
8
8
  attr_reader :logger_params, :glog
9
9
  def initialize
10
10
  @logger_params = STDOUT
11
- @glog = Tlogger.new(STDOUT)
11
+ if ENV['PKERNEL_DEBUG'] == "true"
12
+ @glog = Tlogger::Tlogger.new(STDOUT)
13
+ else
14
+ @glog = Tlogger::Tlogger.new('pkernel.log',10,1024*1024*10)
15
+ end
12
16
  @glog.tag = :pkernel_jce
13
17
  @glog.show_source
14
18
  end
@@ -1,27 +1,31 @@
1
1
 
2
+ require 'pkernel'
3
+
2
4
  require_relative 'provider'
3
5
  require_relative 'csr'
4
6
 
5
- module PkernelJce
7
+ require_relative 'keypair'
6
8
 
7
- #
8
- # Identity
9
- # Identity is abstraction consist of keypair + certificate, stored separately
10
- #
11
- #class Identity
12
- # attr_reader :priv_key, :cert, :keystore, :chain
13
- # def initialize(opts = {})
14
- # @priv_key = opts[:priv_key]
15
- # @cert = opts[:cert]
16
- # @keystore = opts[:keystore]
17
- # @chain = opts[:chain]
18
- # end
19
- #end
20
- # end Identity
21
- #
9
+ # Adding more functions to the parent class
10
+ #
11
+ # Identity
12
+ # Identity is abstraction consist of keypair + certificate, stored separately
13
+ #
14
+ module Pkernel
15
+ class Identity
22
16
 
23
- class Pkernel::Identity
24
-
17
+ def post_init(opts)
18
+ end
19
+
20
+ def certificate=(cert)
21
+ @certificate = cert
22
+ end
23
+
24
+ def chain=(val)
25
+ @chain = val
26
+ end
27
+
28
+ #alias_method :super_key=, :key=
25
29
  def key=(val)
26
30
  @key = val
27
31
  if not @key.nil?
@@ -30,6 +34,7 @@ module PkernelJce
30
34
  end
31
35
  end
32
36
 
37
+ alias_method :super_key, :key
33
38
  def key
34
39
  if @key.nil?
35
40
  if not @privKey.nil?
@@ -50,6 +55,44 @@ module PkernelJce
50
55
  @key
51
56
  end
52
57
 
58
+ def keypair=(val)
59
+ @keypair = val
60
+ end
61
+
62
+ def keypair
63
+ if @keypair.nil?
64
+ if not @key.nil? and @key.is_a?(java.security.KeyPair)
65
+ @keypair = @key
66
+ elsif not @key.nil? and @key.is_a?(java.security.PrivateKey)
67
+ @privKey = @key
68
+ if not @pubKey.nil?
69
+ @keypair = java.security.KeyPair.new(@pubKey,@privKey)
70
+ elsif not @certificate.nil?
71
+ @keypair = java.security.KeyPair.new(PkernelJce::Certificate.public_key(@certificate),@privKey)
72
+ else
73
+ # no public key available
74
+ end
75
+ else
76
+
77
+ if not @privKey.nil?
78
+ if not @pubKey.nil?
79
+ @keypair = java.security.KeyPair.new(@pubKey,@privKey)
80
+ elsif not @certificate.nil?
81
+ @keypair = java.security.KeyPair.new(@certificate.public_key,@privKey)
82
+ else
83
+ # no possible to generate without public key
84
+ end
85
+ else
86
+ # not possible to generate without private key
87
+ end
88
+
89
+ end
90
+ end
91
+
92
+ @keypair
93
+ end
94
+
95
+ alias_method :super_privKey, :privKey
53
96
  def privKey
54
97
  if @privKey.nil? and not @key.nil?
55
98
  @privKey = PkernelJce::KeyPair.private_key(@key)
@@ -57,6 +100,7 @@ module PkernelJce
57
100
  @privKey
58
101
  end
59
102
 
103
+ alias_method :super_pubKey, :pubKey
60
104
  def pubKey
61
105
  if @pubKey.nil?
62
106
  if not @key.nil?
@@ -65,13 +109,14 @@ module PkernelJce
65
109
  @pubKey = PkernelJce::KeyPair.public_key(@certificate)
66
110
  end
67
111
  end
68
-
112
+
69
113
  @pubKey
70
114
  end
71
-
115
+
116
+ alias_method :super_cert, :certificate
72
117
  def certificate
73
- if not @certificate.nil? and @certificate.java_kind_of?(Java::OrgBouncycastleCert::X509CertificateHolder)
74
- @certificate = @certificate.to_java_cert
118
+ if not @certificate.nil?
119
+ @certificate = Certificate.ensure_java_cert(@certificate)
75
120
  end
76
121
  @certificate
77
122
  end
@@ -96,10 +141,17 @@ module PkernelJce
96
141
  PkernelJce::GConf.instance.glog.debug "Provider is nil in Identity object. Setting it to default provider '#{PkernelJce::Provider::DefProvider.name}'"
97
142
  @provider = PkernelJce::Provider.add_default
98
143
  end
99
-
144
+
100
145
  @provider
101
146
  end
102
147
  end
148
+ end
149
+ #
150
+ # Pkernel::Identity extension
151
+ #
152
+
153
+
154
+ module PkernelJce
103
155
 
104
156
  #
105
157
  # IdentityFactory
@@ -137,12 +189,200 @@ module PkernelJce
137
189
  alias_method :build, :build_from_components
138
190
  # end build_from_components
139
191
 
140
- def dump(id, opts = {})
192
+ def dump(id, opts = {}, &block)
141
193
 
142
194
  if id.nil?
143
195
  raise PkernelJce::Error, "Identity object is nil in write to keystore"
144
196
  end
145
197
 
198
+ result = { }
199
+
200
+ format = opts[:format]
201
+ case format
202
+ when :pkcs8, :pk8, :p8
203
+
204
+ res = dump_pk8(id, opts, &block)
205
+
206
+ # private key
207
+ file = opts[:file]
208
+ if file.nil? or file.empty?
209
+ result[:bin] = res[:bin]
210
+ else
211
+ ff = java.io.File.new(file)
212
+ ff.parent_file.mkdirs if not ff.parent_file.exists?
213
+ fos = java.io.FileOutputStream.new(ff)
214
+ fos.write res[:bin].to_java.getBytes
215
+ fos.flush
216
+ fos.close
217
+
218
+ result[:file] = file
219
+ end
220
+
221
+ # certificate
222
+ cfile = opts[:cert_file]
223
+ if not cfile.nil?
224
+ ff = java.io.File.new(cfile)
225
+ ff.parent_file.mkdirs if not ff.parent_file.exists?
226
+ fos = java.io.FileOutputStream.new(ff)
227
+ fos.write res[:cert_bin]
228
+ fos.flush
229
+ fos.close
230
+ result[:cert_file] = cfile
231
+ else
232
+ result[:cert_bin] = res[:cert_bin]
233
+ end
234
+
235
+ # cert chain
236
+ cafile = opts[:ca_file]
237
+ if not cafile.nil?
238
+ ff = java.io.File.new(cafile)
239
+ ff.parent_file.mkdirs if not ff.parent_file.exists?
240
+ fos = java.io.FileOutputStream.new(ff)
241
+ res[:ca_bin].each do |ca|
242
+ fos.write ca
243
+ end
244
+ fos.flush
245
+ fos.close
246
+
247
+ result[:ca_file] = cafile
248
+ else
249
+ result[:ca_bin] = res[:ca_bin]
250
+ end
251
+
252
+ result
253
+
254
+ when :pem
255
+
256
+ res = dump_pem(id, opts, &block)
257
+
258
+ # private key
259
+ file = opts[:file]
260
+ if file.nil? or file.empty?
261
+ result[:bin] = res[:bin]
262
+ else
263
+ ff = java.io.File.new(file)
264
+ ff.parent_file.mkdirs if not ff.parent_file.exists?
265
+ fos = java.io.FileOutputStream.new(ff)
266
+ fos.write res[:bin]
267
+ fos.flush
268
+ fos.close
269
+
270
+ result[:file] = file
271
+ end
272
+
273
+ # public key
274
+ cfile = opts[:pubKey_file]
275
+ if not cfile.nil?
276
+ ff = java.io.File.new(cfile)
277
+ ff.parent_file.mkdirs if not ff.parent_file.exists?
278
+ fos = java.io.FileOutputStream.new(ff)
279
+ fos.write res[:pubKey_bin]
280
+ fos.flush
281
+ fos.close
282
+ result[:pubKey_file] = cfile
283
+ else
284
+ result[:pubKey_bin] = res[:pubKey_bin]
285
+ end
286
+
287
+ # certificate
288
+ cfile = opts[:cert_file]
289
+ if not cfile.nil?
290
+ ff = java.io.File.new(cfile)
291
+ ff.parent_file.mkdirs if not ff.parent_file.exists?
292
+ fos = java.io.FileOutputStream.new(ff)
293
+ fos.write res[:cert_bin]
294
+ fos.flush
295
+ fos.close
296
+ result[:cert_file] = cfile
297
+ else
298
+ result[:cert_bin] = res[:cert_bin]
299
+ end
300
+
301
+ # cert chain
302
+ cafile = opts[:ca_file]
303
+ if not cafile.nil?
304
+ ff = java.io.File.new(cafile)
305
+ ff.parent_file.mkdirs if not ff.parent_file.exists?
306
+ fos = java.io.FileOutputStream.new(ff)
307
+ res[:ca_bin].each do |ca|
308
+ fos.write ca
309
+ end
310
+ fos.flush
311
+ fos.close
312
+
313
+ result[:ca_file] = cafile
314
+ else
315
+ result[:ca_bin] = res[:ca_bin]
316
+ end
317
+
318
+ result
319
+
320
+
321
+ else
322
+ # JCE/JCA keystore
323
+ rres = dump_keystore(id, opts, &block)
324
+
325
+ result.merge!(rres)
326
+
327
+ file = opts[:file]
328
+ if file.nil? or file.empty?
329
+ else
330
+ ff = java.io.File.new(file)
331
+ ff.parent_file.mkdirs if not ff.parent_file.exists?
332
+ fos = java.io.FileOutputStream.new(file)
333
+ fos.write result[:bin]
334
+ fos.flush
335
+ fos.close
336
+
337
+ result[:file] = file
338
+ end
339
+
340
+ result
341
+ end
342
+
343
+ end
344
+
345
+ def dump_to_file(id, file, opts = { }, &block)
346
+ opts = { } if opts.nil?
347
+ raise PkernelJce::Error, "Option for dump to file must be a hash" if not opts.is_a?(Hash)
348
+ dump(id, opts.merge({ file: file }), &block)
349
+ end
350
+
351
+ def dump_to_file_p8(id, idFile, certFile, caFile, password, opts = { }, &block)
352
+ opts = { } if opts.nil?
353
+ raise PkernelJce::Error, "Option for dump to file in pkcs8 format must be a hash" if not opts.is_a?(Hash)
354
+
355
+ raise PkernelJce::Error, "Identity file path cannot be empty" if empty?(idFile)
356
+ raise PkernelJce::Error, "Certificate file path cannot be empty" if empty?(certFile)
357
+ raise PkernelJce::Error, "CA chain file path cannot be empty" if empty?(caFile)
358
+
359
+ dump(id, opts.merge({ file: idFile, cert_file: certFile, ca_file: caFile, format: :pkcs8 }),&block)
360
+ end
361
+
362
+ def load(opts = {}, &block)
363
+
364
+ format = opts[:format]
365
+ case format
366
+ when :pk8, :p8, :pkcs8
367
+ res = load_pk8(opts, &block)
368
+ when :pem
369
+ res = load_pem(opts, &block)
370
+ else
371
+ res = load_keystore(opts, &block)
372
+ end
373
+
374
+ if res[:key].nil?
375
+ raise Pkernel::Error, "Failed to load key from the store."
376
+ end
377
+
378
+ Pkernel::Identity.new( { privKey: res[:key], certificate: res[:cert], chain: res[:chain] } )
379
+ end
380
+ # end load()
381
+
382
+ private
383
+ def dump_keystore(id, opts = { }, &block)
384
+
385
+ result = { }
146
386
  prov = opts[:provider]
147
387
  if prov.nil?
148
388
  prov = PkernelJce::Provider.add_default
@@ -150,35 +390,45 @@ module PkernelJce
150
390
  prov = PkernelJce::Provider.add_provider(prov)
151
391
  end
152
392
 
153
- format = opts[:format]
154
- format = :p12 if format.nil?
155
- sFormat = format
156
- case format
393
+ case opts[:format]
157
394
  when :p12, :pkcs12
158
- PkernelJce::GConf.instance.glog.debug "Loading PKCS12 keystore"
159
- ks = java.security.KeyStore.getInstance("PKCS12",prov)
160
- sFormat = :p12
161
- when :jks
162
- PkernelJce::GConf.instance.glog.debug "Loading JKS keystore"
163
- ks = java.security.KeyStore.getInstance("JKS")
164
- sFormat = :jks
395
+ stype = "PKCS12"
396
+ when :jks, :java
397
+ stype = "jks"
398
+ when :bks
399
+ stype = "bks"
165
400
  else
166
- PkernelJce::GConf.instance.glog.debug "Loading '#{format}' keystore"
167
- if prov.nil?
168
- ks = java.security.KeyStore.getInstance(format)
169
- else
170
- ks = java.security.KeyStore.getInstance(format, prov)
171
- end
172
- sFormat = format
401
+ PkernelJce::GConf.instance.glog.debug "No keystore type given. Default to pkcs12 keystore"
402
+ stype = "PKCS12"
173
403
  end
174
404
 
175
- result = { }
405
+ if prov.nil? or stype == "jks"
406
+ PkernelJce::GConf.instance.glog.debug "Loading #{stype} keystore with null provider"
407
+ ks = java.security.KeyStore.getInstance(stype)
408
+ else
409
+ PkernelJce::GConf.instance.glog.debug "Loading #{stype} keystore with provider #{prov.name}"
410
+ ks = java.security.KeyStore.getInstance(stype,prov)
411
+ end
412
+
176
413
  pass = opts[:password]
177
414
  if pass.nil? or pass.empty?
178
- PkernelJce::GConf.instance.glog.warn "Password is not given to dump identity. Random password shall be generated."
179
- pass = SecureRandom.hex(8)
415
+ if block
416
+ pass = block.call(:prompt_pass)
417
+ end
418
+ end
419
+
420
+ passLen = opts[:password_length] || 8
421
+ # cannot be too small...
422
+ if (passLen/2) < 8
423
+ passLen = 8
424
+ else
425
+ passLen = passLen/2
426
+ end
427
+
428
+ if pass.nil? or pass.empty?
429
+ PkernelJce::GConf.instance.glog.warn "Password is not given to dump identity. Random password of #{passLen*2} characters shall be generated."
430
+ pass = SecureRandom.hex(passLen)
180
431
  result[:password] = pass
181
- #raise PkernelJce::Error, "Password should not be empty for identity storage"
182
432
  end
183
433
 
184
434
  chain = id.chain.map do |c|
@@ -189,50 +439,45 @@ module PkernelJce
189
439
  end
190
440
  end
191
441
 
192
- name = opts[:key_name] || "Pkernel JCE"
442
+ name = opts[:key_name] || opts[:keyName] || opts[:keyname] || Certificate.get_subject_fields(id.certificate,[:cn])[:cn][0]
193
443
 
194
444
  ks.load(nil,nil)
195
445
  ks.setKeyEntry(name, id.privKey, pass.to_java.toCharArray, chain.to_java(java.security.cert.Certificate))
196
- baos = java.io.ByteArrayOutputStream.new
197
-
198
- file = opts[:file]
199
- if file.nil? or file.empty?
200
- ks.store(baos, pass.to_java.toCharArray)
201
- #baos.toByteArray
202
- result[:bin] = baos.toByteArray
203
- else
204
- fos = java.io.FileOutputStream.new(file)
205
- ks.store(fos, pass.to_java.toCharArray)
206
- fos.flush
207
- fos.close
208
-
209
- result[:file] = file
210
- end
211
446
 
447
+ baos = java.io.ByteArrayOutputStream.new
448
+ ks.store(baos, pass.to_java.toCharArray)
449
+ result[:bin] = baos.toByteArray
450
+
212
451
  result
452
+
213
453
  end
454
+ # dump_keystore
214
455
 
215
- def load(opts = {})
456
+ def load_keystore(opts = { }, &block)
457
+
458
+ result = { }
216
459
 
217
460
  prov = opts[:provider]
218
- if prov.nil?
219
- prov = PkernelJce::Provider.add_default
220
- else
461
+ if not prov.nil?
221
462
  prov = PkernelJce::Provider.add_provider(prov)
222
463
  end
223
464
 
224
465
  format = opts[:format]
225
466
  format = :p12 if format.nil?
226
467
  sFormat = format
227
- case format
468
+ case format.to_sym
228
469
  when :p12, :pkcs12
229
470
  PkernelJce::GConf.instance.glog.debug "Loading PKCS12 keystore"
230
- ks = java.security.KeyStore.getInstance("PKCS12",prov)
231
- sFormat = :p12
471
+ pprov = PkernelJce::Provider.add_default
472
+ ks = java.security.KeyStore.getInstance("PKCS12",pprov)
473
+ result[:ks_format] = :p12
232
474
  when :jks
233
475
  PkernelJce::GConf.instance.glog.debug "Loading JKS keystore"
234
476
  ks = java.security.KeyStore.getInstance("JKS")
235
- sFormat = :jks
477
+ result[:ks_format] = :jks
478
+
479
+ when :pk8, :pkcs8, :p8
480
+
236
481
  else
237
482
  PkernelJce::GConf.instance.glog.debug "Loading '#{format}' keystore"
238
483
  if prov.nil?
@@ -240,33 +485,263 @@ module PkernelJce
240
485
  else
241
486
  ks = java.security.KeyStore.getInstance(format.to_s, prov)
242
487
  end
488
+
489
+ result[:ks_format] = format
243
490
  end
244
491
 
245
- pass = opts[:password] || ''
492
+ pass = opts[:password]
493
+
494
+ if (pass.nil? or pass.empty?) and block
495
+ pass = block.call(:prompt_pass)
496
+ end
246
497
 
247
498
  file = opts[:file]
248
499
  bin = opts[:bin]
249
500
  baos = java.io.ByteArrayOutputStream.new
250
501
 
251
- if not file.nil? or not file.empty?
502
+ if not (file.nil? or file.empty?)
252
503
  fis = java.io.FileInputStream.new(file)
253
504
  ks.load(fis,pass.to_java.toCharArray)
254
505
  fis.close
255
- elsif bin.nil?
506
+ elsif not bin.nil?
256
507
  ks.load(java.io.ByteArrayInputStream.new(bin),pass.to_java.toCharArray)
257
508
  else
258
- raise PkernelJce::Error, "No file or bin is given to load identity"
509
+ raise PkernelJce::Error, "No file or bin in keystore format is given to load identity"
259
510
  end
260
-
261
- name = opts[:key_name] || ks.aliases.to_a[0]
262
-
263
- key = ks.getKey(name,pass.to_java.toCharArray)
264
- cert = ks.getCertificate(name)
265
- chain = ks.getCertificateChain(name)
266
511
 
267
- id = Pkernel::Identity.new( { privKey: key, certificate: cert, chain: chain } )
268
- id
512
+ keyname = opts[:keyname] || opts[:keyName] || opts[:key_name]
513
+
514
+ if not (keyname.empty? or keyname.nil?)
515
+ result[:ks_alias] = keyname
516
+ else
517
+ aliases = ks.aliases.to_a
518
+ if aliases.length == 0
519
+ raise PkernelJce::Error, "No alias available from the keystore"
520
+ end
521
+
522
+ if aliases.length > 1
523
+ # more the 1 aliases
524
+ # to ensure the loading is correct, call block or error
525
+ if block
526
+ result[:ks_alias] = block.call(:multiple_aliases, aliases)
527
+ else
528
+ raise PkernelJce::Error, "Multiple aliases exist in the keystores. Please provide keyname to pick one or provide a block for processing"
529
+ end
530
+ else
531
+ result[:ks_alias] = aliases.first
532
+ end
533
+ end
534
+
535
+ result[:key] = ks.getKey(result[:ks_alias],pass.to_java.toCharArray)
536
+ result[:cert] = ks.getCertificate(result[:ks_alias])
537
+ result[:chain] = ks.getCertificateChain(result[:ks_alias])
538
+
539
+ result
540
+ end
541
+ # load_keystore
542
+
543
+ def dump_pem(id,opts,&block)
544
+
545
+ result = { }
546
+ baos = java.io.ByteArrayOutputStream.new
547
+
548
+ pass = opts[:password]
549
+ if (pass.nil? or pass.empty?) and block
550
+ pass = block.call(:prompt_pass)
551
+ end
552
+
553
+ PkernelJce::Provider.add_default
554
+
555
+ writer = org.bouncycastle.openssl.PEMWriter.new(java.io.OutputStreamWriter.new(baos))
556
+ if pass.nil? or pass.empty?
557
+ PkernelJce::GConf.instance.glog.debug "Constructing plain PEM..."
558
+ writer.writeObject(id.privKey)
559
+ else
560
+ PkernelJce::GConf.instance.glog.debug "Constructing encrypted PEM..."
561
+ encryptor = org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder.new("AES-256-GCM").build(pass.to_java.toCharArray)
562
+ writer.writeObject(id.privKey,encryptor)
563
+ end
564
+ writer.flush
565
+ writer.close
566
+ result[:bin] = baos.toByteArray
567
+
568
+ baos.reset
569
+ writer = org.bouncycastle.openssl.PEMWriter.new(java.io.OutputStreamWriter.new(baos))
570
+ writer.writeObject(id.certificate)
571
+ writer.flush
572
+ writer.close
573
+ result[:cert_bin] = baos.toByteArray
574
+
575
+ baos.reset
576
+ writer = org.bouncycastle.openssl.PEMWriter.new(java.io.OutputStreamWriter.new(baos))
577
+ writer.writeObject(id.pubKey)
578
+ writer.flush
579
+ writer.close
580
+ result[:pubKey_bin] = baos.toByteArray
581
+
582
+ cc = []
583
+ id.chain.each do |c|
584
+ baos.reset
585
+ writer = org.bouncycastle.openssl.PEMWriter.new(java.io.OutputStreamWriter.new(baos))
586
+ writer.writeObject(c)
587
+ writer.flush
588
+ writer.close
589
+ cc << baos.toByteArray
590
+ end
591
+ result[:ca_bin] = cc
592
+
593
+ result
594
+
595
+ end
596
+ # dump_pem
597
+
598
+ def load_pem(opts, &block)
599
+ res = { }
600
+ file = opts[:file]
601
+ bin = opts[:bin]
602
+
603
+ prov = PkernelJce::Provider.add_default
604
+
605
+ converter = org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new.setProvider prov
606
+
607
+ if not (file.nil? or file.empty?)
608
+ reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.FileInputStream.new(file)))
609
+ elsif not (bin.nil? or bin.empty?)
610
+ reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.ByteArrayInputStream.new(IoUtils.ensure_java_bytes(bin))))
611
+ else
612
+ raise PkernelJce::Error, "No file or bin in PEM format is given to load identity"
613
+ end
614
+
615
+ obj = reader.readObject
616
+ if obj.java_kind_of? org.bouncycastle.openssl.PEMKeyPair
617
+ res[:keypair] = converter.getKeyPair(obj)
618
+ res[:key] = PkernelJce::KeyPair.private_key(res[:keypair])
619
+
620
+ elsif obj.java_kind_of? org.bouncycastle.openssl.PEMEncryptedKeyPair
621
+
622
+ PkernelJce::GConf.instance.glog.debug "Loading encrypted PEM..."
623
+ pass = opts[:password]
624
+ if (pass.nil? or pass.empty?) and block
625
+ pass = block.call(:prompt_pass)
626
+ end
627
+
628
+ if pass.nil? or pass.empty?
629
+ raise PkernelJce::Error, "The given key file to load is password protected but password is not given. Process shall abort."
630
+ end
631
+
632
+ decryptor = org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder.new.setProvider(prov).build(pass.to_java.toCharArray)
633
+ res[:keypair] = converter.getKeyPair(obj.decryptKeyPair(decryptor))
634
+ res[:key] = PkernelJce::KeyPair.private_key(res[:keypair])
635
+
636
+ elsif obj.java_kind_of? org.bouncycastle.asn1.pkcs.PrivateKeyInfo
637
+ res[:key] = converter.getPrivateKey obj
638
+ else
639
+ raise PkernelJce::Error, "Unknown object for further processing #{obj.class}"
640
+ end
641
+
642
+ if not (opts[:cert_file].nil? or opts[:cert_file].empty?)
643
+ reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.FileInputStream.new(opts[:cert_file])))
644
+ res[:cert] = reader.readObject
645
+ elsif not (opts[:cert_bin].nil? or opts[:cert_bin].empty?)
646
+ reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.ByteArrayInputStream.new(IoUtils.ensure_java_bytes(opts[:cert_bin]))))
647
+ res[:cert] = reader.readObject
648
+ end
649
+
650
+ if not (opts[:ca_file].nil? or opts[:ca_file].empty?)
651
+ reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.FileInputStream.new(opts[:ca_file])))
652
+ res[:chain] = []
653
+ o = reader.readObject
654
+ while(o != nil)
655
+ res[:chain] << o
656
+ o = reader.readObject
657
+ end
658
+ elsif not (opts[:ca_bin].nil? or opts[:ca_bin].empty?)
659
+ reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.ByteArrayInputStream.new(IoUtils.ensure_java_bytes(opts[:ca_bin]))))
660
+ res[:chain] = []
661
+ o = reader.readObject
662
+ while(o != nil)
663
+ res[:chain] << o
664
+ o = reader.readObject
665
+ end
666
+ end
667
+
668
+ res
669
+
670
+ end
671
+ # load_pem
672
+
673
+ # dump_pk8()
674
+ def dump_pk8(id, opts, &block)
675
+
676
+ PkernelJce::GConf.instance.glog.debug "Dump to PKCS8 format..."
677
+
678
+ result = { }
679
+
680
+ pass = opts[:password]
681
+ if (pass.nil? or pass.empty?) and block
682
+ pass = block.call(:prompt_pass)
683
+ end
684
+
685
+ prov = opts[:provider]
686
+ if not prov.nil?
687
+ prov = PkernelJce::Provider.add_provider(prov)
688
+ end
689
+
690
+ # private key only
691
+ # remove file parameter if given
692
+ # because we want the dump to be available here
693
+ keyDumpPara = opts.clone
694
+ keyDumpPara.delete(:file)
695
+ # KeyPair already using the PKCS8 format for output... might as well just reuse...
696
+ rres = PkernelJce::KeyPairEngine.dump(id.keypair, keyDumpPara, &block)
697
+
698
+ result[:bin] = rres
699
+
700
+ result[:cert_bin] = PkernelJce::CertificateEngine.dump(id.certificate, { outForm: :pem })
701
+
702
+ cc = []
703
+ id.chain.each do |c|
704
+ cc << PkernelJce::CertificateEngine.dump(c, { outForm: :pem })
705
+ end
706
+
707
+ result[:ca_bin] = cc
708
+
709
+ result
710
+
711
+ end
712
+ # dump_pk8
713
+
714
+ def load_pk8(opts, &block)
715
+
716
+ res = { }
717
+ pass = opts[:password]
718
+ if (pass.nil? or pass.empty?) and block
719
+ pass = block.call(:prompt_pass)
720
+ end
721
+
722
+ prov = opts[:provider]
723
+ if not prov.nil?
724
+ prov = PkernelJce::Provider.add_provider(prov)
725
+ end
726
+
727
+ key = PkernelJce::KeyPairEngine.load(opts)
728
+
729
+ res[:key] = key
730
+
731
+ certPara = { }
732
+ certPara[:file] = opts[:cert_file] if not (opts[:cert_file].nil? or opts[:cert_file].empty?)
733
+ certPara[:bin] = opts[:cert_bin] if not (opts[:cert_bin].nil? or opts[:cert_file].empty?)
734
+ res[:cert] = PkernelJce::CertificateEngine.load(certPara)
735
+
736
+ chainPara = { multiple: true }
737
+ chainPara[:file] = opts[:ca_file] if not (opts[:ca_file].nil? or opts[:ca_file].empty?)
738
+ chainPara[:bin] = opts[:ca_bin] if not (opts[:ca_bin].nil? or opts[:ca_bin].empty?)
739
+ res[:chain] = PkernelJce::CertificateEngine.load(chainPara)
740
+
741
+ res
742
+
269
743
  end
744
+ # load_pk8
270
745
 
271
746
  end
272
747
  # end IdentityFactory