pkernel_jce 0.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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