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.
@@ -21,6 +21,8 @@ module PkernelJce
21
21
  def IoUtils.ensure_java_bytes(bin)
22
22
  if not bin.java_kind_of?(Java::byte[])
23
23
  bin.to_java_bytes
24
+ elsif bin.is_a?(String)
25
+ bin = bin.to_java.getBytes
24
26
  else
25
27
  bin
26
28
  end
@@ -0,0 +1,134 @@
1
+
2
+
3
+ module PkernelJce
4
+ module JFile
5
+ def JFile.create_temp_file(opts = { })
6
+ prefix = opts[:prefix]
7
+ suffix = opts[:suffix]
8
+ dir = opts[:directory]
9
+ java.io.File.createTempFile(prefix,suffix,dir)
10
+ end # create_temp_file
11
+
12
+ def JFile.absolute_path(file)
13
+ if file.nil?
14
+ raise PkernelJce::Error, "Cannot get absolute path for file is nil"
15
+ else
16
+ file.absolute_path
17
+ end
18
+ end # absolute_path
19
+
20
+ def JFile.equal?(*files,&block)
21
+ if files.length > 1
22
+
23
+ if block
24
+ bufLen = block.call(:bufLen)
25
+ end
26
+ bufLen = bufLen || 102400
27
+
28
+ equal = false
29
+ result = nil
30
+ md = java.security.MessageDigest.getInstance("SHA256")
31
+ files.each do |f|
32
+ ff = java.io.File.new(f)
33
+ if ff.exist?
34
+ buf = Java::byte[bufLen].new
35
+ fis = java.io.FileInputStream.new(ff)
36
+ while((read = fis.read(buf,0,buf.length)) != -1)
37
+ md.update(buf,0,read)
38
+ end
39
+ res = md.digest
40
+ if result.nil?
41
+ result = res
42
+ elsif not java.util.Arrays.is_equals(res, result)
43
+ equal = false
44
+ break
45
+ else
46
+ result = res
47
+ end
48
+
49
+ md.reset
50
+ else
51
+ raise PkernelJce::Error, "Given file to compare equal '#{f}' does not exist"
52
+ end
53
+ end
54
+
55
+ equal
56
+ else
57
+ true
58
+ end
59
+ end # equals?
60
+
61
+ def JFile.copy(src,dest,opts = { },&block)
62
+ raise PkernelJce::Error, "Source cannot be nil or empty" if src.nil? or src.empty?
63
+ raise PkernelJce::Error, "Destination cannot be nil" if dest.nil?
64
+
65
+ if src.is_a?(java.io.InputStream)
66
+ src = src
67
+ srcLength = src.length
68
+ elsif src.is_a?(String)
69
+ # assume is file path?
70
+ f = java.io.File.new(src)
71
+ raise PkernelJce::Error, "Given file doesn't exist [#{f.absolute_path}]" if not f.exists
72
+ raise PkernelJce::Error, "Cannot read source file from a directory [#{f.absolute_path}]" if f.is_directory?
73
+ src = java.io.FileInputStream.new(f)
74
+ srcLength = f.length
75
+ else
76
+ raise PkernelJce::Error, "Unsupported source file type #{src.class}"
77
+ end
78
+
79
+ if dest.is_a?(java.io.OutputStream)
80
+ PkernelJce::GConf.instance.glog.debug "Given dest is an OutputStream. Direct use the object."
81
+ os = dest
82
+ elsif dest.is_a?(String)
83
+ # assume is file path?
84
+ f = java.io.File.new(dest)
85
+ raise PkernelJce::Error, "Cannot write dest to a directory [#{f.absolute_path}]" if f.is_directory?
86
+
87
+ PkernelJce::GConf.instance.glog.debug "Opening given path #{f.absolute_path} to copy file into"
88
+ os = java.io.FileOutputStream.new(f)
89
+
90
+ else
91
+ raise PkernelJce::Error, "Unsupported destination type #{dest.class}"
92
+ end
93
+
94
+ bufSize = opts[:bufSize] || 1024000
95
+ b = Java::byte[bufSize].new
96
+ totalWritten = 0
97
+ while((read = src.read(b,0,b.length)) != -1)
98
+ if block
99
+ block.call(:before_write, { buf: b, from: 0, len: read })
100
+ end
101
+
102
+ os.write(b,0,read)
103
+
104
+ totalWritten += read
105
+ if block
106
+ block.call(:progress, { total: srcLength, written: read, processed: totalWritten })
107
+ end
108
+ end
109
+
110
+ end # copy
111
+
112
+ def to_memory(file, opts = { }, &block)
113
+ raise PkernelJce::Error, "No file given" if file.nil?
114
+ f = java.io.File.new(file)
115
+ raise PkernelJce::Error, "Given file #{f.absolute_path} does not exist" if not f.exists
116
+ raise PkernelJce::Error, "Given file #{f.absolute_path} is a directory" if f.directory?
117
+
118
+ total = f.length
119
+ bufSize = opts[:bufSize] || 1024000
120
+ b = Java::byte[bufSize].new
121
+ baos = java.io.ByteArrayOutputStream.new
122
+ processed = 0
123
+ fis = java.io.FileInputStream.new(f)
124
+ while((read = fis.read(b,0,b.length)) != -1)
125
+ baos.write(b,0,read)
126
+ processed += read
127
+
128
+ block.call(:progress, { total: total, processed: processed, wwritten: read }) if block
129
+ end
130
+
131
+ baos.toByteArray
132
+ end # to_memory
133
+ end # module JFile
134
+ end
@@ -0,0 +1,7 @@
1
+
2
+
3
+ module PkernelJce
4
+ module JMemBuf
5
+
6
+ end
7
+ end
@@ -4,19 +4,11 @@ require 'pkernel'
4
4
  require_relative 'provider'
5
5
  require_relative 'global'
6
6
 
7
+ require_relative 'converter'
8
+
7
9
  module PkernelJce
8
10
  module KeyPair
9
11
 
10
- def KeyPair.capabilities(type)
11
- case type
12
- when :rsa
13
- when :dsa
14
- when :ecc
15
- else
16
- {}
17
- end
18
- end
19
-
20
12
  def generate(algo, conf = {})
21
13
 
22
14
  log = conf[:log]
@@ -40,6 +32,7 @@ module PkernelJce
40
32
 
41
33
  kpg.java_send :initialize, [Java::int], len
42
34
  kpg.generate_key_pair
35
+
43
36
  when "DSA"
44
37
  len = conf[:len] || 2048
45
38
  log.debug "Generating DSA #{len} bits with provider #{prov == nil ? 'default' : prov.name}"
@@ -54,6 +47,17 @@ module PkernelJce
54
47
  when "ECC","EC"
55
48
  # this only supported by bc?
56
49
  curve = conf[:curve] || "prime256v1"
50
+ curve.strip!
51
+ # Fp
52
+ # X9.62 : prime192v1, prime192v2, prime192v3, prime239v1, prime239v2, prime239v3, prime256v1
53
+ # SEC : secp192k1, secp192r1, secp224k1, secp224r1, secp256k1, secp256r1, secp384r1, secp521r1
54
+ # NIST: P-224, P-256, P-384, P-521
55
+ # F 2m
56
+ # X9.62 : c2pnb163v1, c2pnb163v2, c2pnb163v3, c2pnb176w1, c2tnb191v1, c2tnb191v2, c2tnb191v3, c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, c2pnb272w1, c2pnb304w1, c2tnb359v1, c2pnb368w1, c2tnb431r1
57
+ # SEC: sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1
58
+ # NIST : B-163, B-233, B-283, B-409, B-571
59
+ # Teletrust : brainpoolp160r1, brainpoolp160t1, brainpoolp192r1, brainpoolp192t1, brainpoolp224r1, brainpoolp224t1, brainpoolp256r1, brainpoolp256t1, brainpoolp320r1, brainpoolp320t1, brainpoolp384r1, brainpoolp384t1, brainpoolp512r1, brainpoolp512t1
60
+ # GostR3410-2001-CryptoPro-A, GostR3410-2001-CryptoPro-XchB, GostR3410-2001-CryptoPro-XchA, GostR3410-2001-CryptoPro-C, GostR3410-2001-CryptoPro-B
57
61
  if prov.nil?
58
62
  #kpg = java.security.KeyPairGenerator.getInstance("ECDSA")
59
63
  # default Java does not have ECDSA yet as of Java 8
@@ -65,6 +69,48 @@ module PkernelJce
65
69
  kpg = java.security.KeyPairGenerator.getInstance("ECDSA", prov)
66
70
  kpg.java_send :initialize, [java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom], java.security.spec.ECGenParameterSpec.new(curve), java.security.SecureRandom.new
67
71
  kpg.generate_key_pair
72
+
73
+ when "DH"
74
+
75
+ len = conf[:len] || 1024
76
+ certainty = conf[:certainty] || org.bouncycastle.jcajce.provider.asymmetric.util.PrimeCertaintyCalculator.getDefaultCertainty(len)
77
+ # for DH key, these two values can be shared...
78
+ # https://news.ycombinator.com/item?id=10397326
79
+ # this two values shall be in hex
80
+ p = conf[:p]
81
+ g = conf[:g]
82
+
83
+ if not p.nil?
84
+ p = java.math.BigInteger.new(p,16)
85
+ end
86
+
87
+ if not g.nil?
88
+ g = java.math.BigInteger.new(g,16)
89
+ end
90
+
91
+ prov = PkernelJce::Provider::DefProvider
92
+
93
+ if not (p.nil? and g.nil?)
94
+ log.debug "Generating DH key from given p and g"
95
+ gparam = org.bouncycastle.crypto.params.DHParameters.new(p,g)
96
+
97
+ else
98
+
99
+ log.debug "Generating DH #{len} bits with provider #{prov.name}, certainty : #{certainty}."
100
+ if len > 1024
101
+ log.warn "Generating #{len} bits of DH key may take some time... so be patient..."
102
+ end
103
+
104
+ dhParamGen = org.bouncycastle.crypto.generators.DHParametersGenerator.new
105
+ dhParamGen.init(len,certainty, java.security.SecureRandom.new)
106
+ gparam = dhParamGen.generate_parameters
107
+ end
108
+
109
+ kgParam = org.bouncycastle.crypto.params.DHKeyGenerationParameters.new(java.security.SecureRandom.new, gparam)
110
+ kpg = org.bouncycastle.crypto.generators.DHKeyPairGenerator.new
111
+ kpg.init(kgParam)
112
+ kpg.generateKeyPair
113
+
68
114
  else
69
115
  log.error "Unknown '#{algo}' for java keypair"
70
116
  raise PkernelJce::Error, "Unknown algo '#{algo}' for java keypair"
@@ -74,20 +120,28 @@ module PkernelJce
74
120
  #
75
121
 
76
122
  def KeyPair.key_type(key)
77
- if key.java_kind_of?(java.security.KeyPair)
123
+
124
+ case key
125
+ when java.security.KeyPair, org.bouncycastle.crypto.AsymmetricCipherKeyPair
78
126
  privKey = key.getPrivate
79
127
  else
80
128
  # given is private key
81
- privKey = key
129
+ if KeyPair.is_private_key?(key)
130
+ privKey = key
131
+ else
132
+ raise PkernelJce::Error, "key_type API only check for keypair and private key. For public key type shall call pub_key_type() API. Given key is #{key}"
133
+ end
82
134
  end
83
-
135
+
84
136
  case privKey
85
- when java.security.interfaces.RSAPrivateCrtKey
137
+ when java.security.interfaces.RSAPrivateCrtKey, Java::OrgBouncycastleCryptoParams::RSAPrivateCrtKeyParameters
86
138
  Pkernel::KeyPair::RSA_KEY_NAME
87
- when Java::sun.security.provider.DSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.dsa.BCDSAPrivateKey
139
+ when Java::sun.security.provider.DSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.dsa.BCDSAPrivateKey, Java::OrgBouncycastleCryptoParams::DSAPrivateKeyParameters
88
140
  Pkernel::KeyPair::DSA_KEY_NAME
89
- when org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
141
+ when org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey, Java::OrgBouncycastleCryptoParams::ECPrivateKeyParameters, Java::SunSecurityEc::ECPrivateKeyImpl
90
142
  Pkernel::KeyPair::EC_KEY_NAME
143
+ when org.bouncycastle.crypto.params.DHPrivateKeyParameters
144
+ Pkernel::KeyPair::DH_KEY_NAME
91
145
  else
92
146
  raise PkernelJce::Error, "Unknown priv key type '#{privKey.class}'"
93
147
  end
@@ -96,6 +150,19 @@ module PkernelJce
96
150
  # end get_key_type
97
151
  #
98
152
 
153
+ def KeyPair.is_private_key?(key)
154
+ if key.nil?
155
+ false
156
+ else
157
+ case key
158
+ when java.security.interfaces.RSAPrivateCrtKey, Java::sun.security.provider.DSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.dsa.BCDSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey, Java::OrgBouncycastleCryptoParams::RSAPrivateCrtKeyParameters, Java::OrgBouncycastleCryptoParams::DSAPrivateKeyParameters, Java::OrgBouncycastleCryptoParams::ECPrivateKeyParameters, Java::SunSecurityEc::ECPrivateKeyImpl, org.bouncycastle.crypto.AsymmetricCipherKeyPair, java.security.KeyPair
159
+ true
160
+ else
161
+ false
162
+ end
163
+ end
164
+ end
165
+
99
166
  def KeyPair.pub_key_type(key)
100
167
  if key.java_kind_of?(java.security.KeyPair)
101
168
  pubKey = key.public
@@ -110,8 +177,10 @@ module PkernelJce
110
177
  Pkernel::KeyPair::RSA_KEY_NAME
111
178
  when Java::sun.security.provider.DSAPublicKey, Java::OrgBouncycastleJcajceProviderAsymmetricDsa::BCDSAPublicKey
112
179
  Pkernel::KeyPair::DSA_KEY_NAME
113
- when Java::OrgBouncycastleJcajceProviderAsymmetricEc::BCECPublicKey
180
+ when Java::OrgBouncycastleJcajceProviderAsymmetricEc::BCECPublicKey, Java::SunSecurityEc::ECPublicKeyImpl
114
181
  Pkernel::KeyPair::EC_KEY_NAME
182
+ when org.bouncycastle.crypto.params.DHPublicKeyParameters
183
+ Pkernel::KeyPair::DH_KEY_NAME
115
184
  else
116
185
  raise PkernelJce::Error, "Unknown pub key type '#{pubKey.class}'"
117
186
  end
@@ -134,19 +203,6 @@ module PkernelJce
134
203
  end
135
204
  end
136
205
 
137
- def KeyPair.is_private_key?(key)
138
- if key.nil?
139
- false
140
- else
141
- case key
142
- when java.security.interfaces.RSAPrivateCrtKey, Java::sun.security.provider.DSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.dsa.BCDSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
143
- true
144
- else
145
- false
146
- end
147
- end
148
- end
149
-
150
206
  def KeyPair.is_keypair?(key)
151
207
  if key.nil?
152
208
  false
@@ -160,7 +216,7 @@ module PkernelJce
160
216
  end
161
217
  end
162
218
 
163
- def KeyPair.public_key(priv)
219
+ def KeyPair.public_key(priv, opts = { })
164
220
  if priv.nil?
165
221
  raise PkernelJce::Error, "Cannot derive public key from nil key"
166
222
  else
@@ -177,11 +233,40 @@ module PkernelJce
177
233
  prov = PkernelJce::Provider.add_default
178
234
  java.security.KeyFactory.getInstance("DSA",prov).generatePublic(spec)
179
235
  when Pkernel::KeyPair::EC_KEY_NAME
180
- d = priv.d;
181
- q = priv.parameters.g.to_java.multiply(d);
182
- pubSpec = org.bouncycastle.jce.spec.ECPublicKeySpec.new(q, priv.parameters);
183
- prov = PkernelJce::Provider.add_default
184
- java.security.KeyFactory.getInstance("EC",prov).generatePublic(pubSpec)
236
+ case priv
237
+ # No way to recover public key using SUN provider yet
238
+ #when Java::SunSecurityEc::ECPrivateKeyImpl
239
+ # this uses BC also so add provider first
240
+ #pProv = PkernelJce::Provider.add_default
241
+ #curveName = priv.params.name.split(" ")[0]
242
+
243
+ #ecSpec = org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util.convertSpec(priv.params,false)
244
+ #q = ecSpec.g.to_java.multiply(priv.s)
245
+ #bcW = ecSpec.curve.decodePoint(q.getEncoded(false))
246
+ ##w = org.bouncycastle.math.ec.ECPoint.new(bcW.getAffineXCoord.toBigInteger, bcW.getAffineYCoord.toBigInteger)
247
+ #w = java.security.spec.ECPoint.new(bcW.getAffineXCoord.toBigInteger, bcW.getAffineYCoord.toBigInteger)
248
+ #curveParam = org.bouncycastle.jce.ECNamedCurveTable.getParameterSpec(curveName)
249
+ ##keySpec = org.bouncycastle.jce.spec.ECPublicKeySpec.new(w,curveParam)
250
+ #keySpec = java.security.spec.ECPublicKeySpec.new(w,curveParam)
251
+
252
+ ##java.security.KeyFactory.getInstance("EC",pProv).generatePublic(keySpec)
253
+
254
+ when Java::OrgBouncycastleCryptoParams::ECPrivateKeyParameters, org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
255
+ d = priv.d
256
+ q = priv.parameters.g.to_java.multiply(d)
257
+ pubSpec = org.bouncycastle.jce.spec.ECPublicKeySpec.new(q, priv.parameters)
258
+ prov = PkernelJce::Provider.add_default
259
+ java.security.KeyFactory.getInstance("EC",prov).generatePublic(pubSpec)
260
+ else
261
+ raise PkernelJce::Error, "Haven't figure out how to convert #{priv.class} into public key yet..."
262
+ end
263
+ #p priv
264
+ #p priv.methods.sort
265
+ #d = priv.d;
266
+ #q = priv.parameters.g.to_java.multiply(d);
267
+ #pubSpec = org.bouncycastle.jce.spec.ECPublicKeySpec.new(q, priv.parameters);
268
+ #prov = PkernelJce::Provider.add_default
269
+ #java.security.KeyFactory.getInstance("EC",prov).generatePublic(pubSpec)
185
270
  else
186
271
  end
187
272
  elsif priv.java_kind_of?(java.security.PublicKey)
@@ -200,6 +285,21 @@ module PkernelJce
200
285
  # end public_key(priv)
201
286
  #
202
287
 
288
+ #
289
+ # Compare 2 public keys
290
+ #
291
+ def KeyPair.is_public_key_equals?(pub1, pub2)
292
+ if not (pub1.nil? and pub2.nil?)
293
+ pubkey1 = KeyPair.public_key(pub1)
294
+ pubkey2 = KeyPair.public_key(pub2)
295
+
296
+ pubkey1.equals(pubkey2)
297
+
298
+ else
299
+ false
300
+ end
301
+ end # is_public_key_equals?
302
+
203
303
  # harmonize the private key acquiring
204
304
  # There are BC and Java, keypair and private key
205
305
  def KeyPair.private_key(kp)
@@ -247,7 +347,48 @@ module PkernelJce
247
347
  end
248
348
  end
249
349
 
250
- def dump(keypair, options = {})
350
+ def KeyPair.key_size(kp)
351
+ if KeyPair.is_keypair?(kp)
352
+ type = PkernelJce::KeyPair.key_type(KeyPair.private_key(kp))
353
+ elsif KeyPair.is_public_key?(kp)
354
+ type = PkernelJce::KeyPair.pub_key_type(kp)
355
+ elsif Certificate.is_cert_object?(kp)
356
+ type = PkernelJce::KeyPair.pub_key_type(Certificate.public_key(kp))
357
+ elsif KeyPair.is_private_key?(kp)
358
+ type = PkernelJce::KeyPair.key_type(kp)
359
+ else
360
+ raise PkernelJce::Error, "Unknown key type to derive signing key algo from"
361
+ end
362
+
363
+ case type
364
+ when Pkernel::KeyPair::RSA_KEY_NAME
365
+ if PkernelJce::KeyPair::is_keypair?(kp)
366
+ rsaKey = PkernelJce::KeyPair.private_key(kp)
367
+ elsif PkernelJce::KeyPair::is_private_key?(kp)
368
+ rsaKey = PkernelJce::KeyPair.private_key(kp)
369
+ elsif PkernelJce::KeyPair::is_public_key?(kp)
370
+ rsaKey = PkernelJce::KeyPair::public_key(kp)
371
+ end
372
+
373
+ rsaKey.modulus.bit_length
374
+
375
+ when Pkernel::KeyPair::DSA_KEY_NAME
376
+ if PkernelJce::KeyPair::is_keypair?(kp)
377
+ dsaKey = PkernelJce::KeyPair.private_key(kp)
378
+ elsif PkernelJce::KeyPair::is_private_key?(kp)
379
+ dsaKey = PkernelJce::KeyPair.private_key(kp)
380
+ elsif PkernelJce::KeyPair::is_public_key?(kp)
381
+ dsaKey = PkernelJce::KeyPair::public_key(kp)
382
+ end
383
+
384
+ dsaKey.params.p.bit_length
385
+
386
+ when Pkernel::KeyPair::EC_KEY_NAME
387
+
388
+ end
389
+ end
390
+
391
+ def dump(keypair, options = {} ,&block)
251
392
  if keypair.nil?
252
393
  raise PkernelJce::Error, "Keypair is nil during writing PEM"
253
394
  end
@@ -257,43 +398,115 @@ module PkernelJce
257
398
  file = options[:file]
258
399
  pass = options[:password]
259
400
 
260
- binOut = java.io.ByteArrayOutputStream.new
401
+ #binOut = java.io.ByteArrayOutputStream.new
261
402
 
262
- if file.nil?
263
- PkernelJce::GConf.instance.glog.debug "Dump output to memory"
264
- # return binary to caller
265
- writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(binOut));
266
- else
267
- PkernelJce::GConf.instance.glog.debug "Dump output to file '#{file}'"
268
- out = java.io.FileOutputStream.new(file)
269
- writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(out));
403
+ if (pass.nil? or pass.empty?) and block
404
+ pass = block.call(:prompt_pass)
270
405
  end
271
406
 
272
- begin
273
- if pass.nil? or pass.empty?
274
- writer.writeObject(keypair.getPrivate)
275
- else
276
- builder = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8EncryptorBuilder.new(org.bouncycastle.openssl.PKCS8Generator::AES_256_CBC).setProvider(PkernelJce::Provider::DefProvider).setPasssword(pass.to_java.toCharArray());
407
+ ## BC API
408
+ #if file.nil?
409
+ # PkernelJce::GConf.instance.glog.debug "Dump output to memory"
410
+ # # return binary to caller
411
+ # writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(binOut));
412
+ #else
413
+ # PkernelJce::GConf.instance.glog.debug "Dump output to file '#{file}'"
414
+ # out = java.io.FileOutputStream.new(file)
415
+ # writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(out));
416
+ #end
417
+
418
+ #begin
419
+ # if pass.nil? or pass.empty?
420
+ # writer.writeObject(keypair.getPrivate)
421
+ # else
422
+ # builder = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8EncryptorBuilder.new(org.bouncycastle.openssl.PKCS8Generator::AES_256_CBC).setProvider(PkernelJce::Provider::DefProvider).setPasssword(pass.to_java.toCharArray());
423
+
424
+ # pkcs8 = org.bouncycastle.openssl.jcajce.JcaPKCS8Generator.new(keypair.getPrivate, builder.build);
425
+ # writer.writeObject(pkcs8)
426
+ # end
427
+ #ensure
428
+ # writer.flush
429
+ # writer.close
430
+ #end
431
+
432
+ # Java API
433
+ prov = options[:provider]
434
+ if not prov.nil?
435
+ prov = PkernelJce::Provider.add_provider(prov)
436
+ end
277
437
 
278
- pkcs8 = org.bouncycastle.openssl.jcajce.JcaPKCS8Generator.new(keypair.getPrivate, builder.build);
279
- writer.writeObject(pkcs8)
438
+ if pass.nil? or pass.empty?
439
+ PkernelJce::GConf.instance.glog.warn "Dumping of private key without password!"
440
+ encInfo = java.security.spec.PKCS8EncodedKeySpec.new(PkernelJce::KeyPair.private_key(keypair).encoded)
441
+ else
442
+ pbeAlgo = options[:pbeAlgo]
443
+ # todo test this algo with openssl and see...
444
+ pbeAlgo = "PBEWithSHA1AndRC4_128" if pbeAlgo.nil? or pbeAlgo.empty?
445
+
446
+ salt = Java::byte[32].new
447
+ Java::JavaSecurity::SecureRandom.new.nextBytes(salt)
448
+ pbeParamSpec = Java::JavaxCryptoSpec::PBEParameterSpec.new(salt,88)
449
+ pbeKeySpec = Java::JavaxCryptoSpec::PBEKeySpec.new(pass.to_java.toCharArray)
450
+ if not prov.nil?
451
+
452
+ secKeyFact = Java::JavaxCrypto::SecretKeyFactory.getInstance(pbeAlgo,prov)
453
+ pbeKey = secKeyFact.generateSecret(pbeKeySpec)
454
+ cipher = Java::JavaxCrypto::Cipher.getInstance(pbeAlgo,prov)
455
+ cipher.init(Java::JavaxCrypto::Cipher::ENCRYPT_MODE,pbeKey,pbeParamSpec)
456
+ output = cipher.doFinal(PkernelJce::KeyPair.private_key(keypair).getEncoded())
457
+ algoParam = Java::JavaSecurity::AlgorithmParameters.getInstance(pbeAlgo,prov)
458
+
459
+ else
460
+ secKeyFact = Java::JavaxCrypto::SecretKeyFactory.getInstance(pbeAlgo)
461
+ pbeKey = secKeyFact.generateSecret(pbeKeySpec)
462
+ cipher = Java::JavaxCrypto::Cipher.getInstance(pbeAlgo)
463
+ cipher.init(Java::JavaxCrypto::Cipher::ENCRYPT_MODE,pbeKey,pbeParamSpec)
464
+ output = cipher.doFinal(PkernelJce::KeyPair.private_key(keypair).getEncoded())
465
+ algoParam = Java::JavaSecurity::AlgorithmParameters.getInstance(pbeAlgo)
280
466
  end
281
- ensure
282
- writer.flush
283
- writer.close
467
+
468
+ algoParam.init(pbeParamSpec)
469
+ encPrivInfo = Java::JavaxCrypto::EncryptedPrivateKeyInfo.new(algoParam,output)
470
+ encInfo = encPrivInfo
284
471
  end
285
472
 
286
- if file.nil?
287
- binOut.toByteArray
473
+ cont = []
474
+ keyType = KeyPair.key_type(keypair)
475
+ case keyType
476
+ when Pkernel::KeyPair::RSA_KEY_NAME
477
+ cont << "-----BEGIN RSA PRIVATE KEY-----"
478
+ cont << PkernelJce::Converter.to_mb64(encInfo.getEncoded)
479
+ cont << "-----END RSA PRIVATE KEY-----"
480
+ when Pkernel::KeyPair::DSA_KEY_NAME
481
+ cont << "-----BEGIN DSA PRIVATE KEY-----"
482
+ cont << PkernelJce::Converter.to_mb64(encInfo.getEncoded)
483
+ cont << "-----END DSA PRIVATE KEY-----"
484
+ when Pkernel::KeyPair::EC_KEY_NAME
485
+ cont << "-----BEGIN EC PRIVATE KEY-----"
486
+ cont << PkernelJce::Converter.to_mb64(encInfo.getEncoded)
487
+ cont << "-----END EC PRIVATE KEY-----"
488
+ else
489
+ raise PkernelJce::Error, "Unsupported key type #{keyType}"
288
490
  end
491
+
492
+ pkcs8Envelope = cont.join("\n")
493
+
494
+ #pkcs8Envelope = encPrivInfo.getEncoded()
495
+
496
+ if not file.nil?
497
+ fos = java.io.FileOutputStream.new(file)
498
+ fos.write(pkcs8Envelope.to_java.getBytes)
499
+ fos.flush
500
+ fos.close
501
+ end
502
+
503
+ pkcs8Envelope
504
+
289
505
  end
290
506
  # end dump
291
507
 
292
508
  def load(opts = {}, &block)
293
- #is = opts[:inputStream]
294
- #if is.nil?
295
- # raise PkernelJce::Error, "InputStream not given"
296
- #end
509
+
297
510
  file = opts[:file]
298
511
  bin = opts[:bin]
299
512
 
@@ -319,40 +532,145 @@ module PkernelJce
319
532
  raise PkernelJce::Error, "No 'file' or 'bin' is defined to load keypair"
320
533
  end
321
534
 
322
- prov = opts[:provider] || PkernelJce::Provider::DefProvider
323
- prov = PkernelJce::Provider.add_provider(prov)
324
-
325
- reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.ByteArrayInputStream.new(baos.toByteArray)))
326
- obj = reader.readObject
327
- #p obj.inspect
328
- #p obj.methods.sort
329
- #p obj.java_kind_of?(org.bouncycastle.openssl.PEMEncryptedKeyPair)
330
- if obj.is_a?(org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo)
331
- pass = opts[:password]
332
- if pass.nil?
333
- if block
334
- pass = block.call(:password)
335
- else
336
- raise PkernelJce::Error, "PEM key is encrypted. Please provide a password to load the key."
337
- end
535
+ prov = opts[:provider]
536
+ if not prov.nil?
537
+ prov = PkernelJce::Provider.add_provider(prov)
538
+ end
539
+
540
+ pass = opts[:password]
541
+ if (pass.nil? or pass.empty?) and block
542
+ pass = block.call(:prompt_pass)
543
+ end
544
+
545
+ cont = String.from_java_bytes(baos.toByteArray)
546
+ cont.gsub!("-----BEGIN RSA PRIVATE KEY-----","")
547
+ cont.gsub!("-----END RSA PRIVATE KEY-----","")
548
+ cont.gsub!("-----BEGIN DSA PRIVATE KEY-----","")
549
+ cont.gsub!("-----END DSA PRIVATE KEY-----","")
550
+ cont.gsub!("-----BEGIN EC PRIVATE KEY-----","")
551
+ cont.gsub!("-----END EC PRIVATE KEY-----","")
552
+ econt = PkernelJce::Converter.from_mb64(cont)
553
+ #fos = java.io.FileOutputStream.new("test.bin")
554
+ #fos.write(econt)
555
+ #fos.flush
556
+ #fos.close
557
+
558
+ # Java API
559
+ if not (pass.nil? or pass.empty?)
560
+
561
+ PkernelJce::GConf.instance.glog.debug "Password protected envelope"
562
+ encPrivInfo = Java::JavaxCrypto::EncryptedPrivateKeyInfo.new(econt)
563
+ cipher = Java::JavaxCrypto::Cipher::getInstance(encPrivInfo.getAlgName())
564
+ pbeKeySpec = Java::JavaxCryptoSpec::PBEKeySpec.new(pass.to_java.toCharArray)
565
+ if(prov != nil)
566
+ secKeyFact = Java::JavaxCrypto::SecretKeyFactory.getInstance(encPrivInfo.getAlgName(),prov)
567
+ else
568
+ secKeyFact = Java::JavaxCrypto::SecretKeyFactory.getInstance(encPrivInfo.getAlgName())
338
569
  end
339
- decProv = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder.new.setProvider(PkernelJce::Provider::DefProvider).build(pass.to_java.toCharArray)
340
- keyinfo = obj.decryptPrivateKeyInfo(decProv)
570
+ pbeKey = secKeyFact.generateSecret(pbeKeySpec)
571
+
572
+ cipher.init(Java::JavaxCrypto::Cipher::DECRYPT_MODE, pbeKey,encPrivInfo.getAlgParameters())
341
573
 
342
- converter = org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new
343
- converter.getPrivateKey(keyinfo)
574
+ pkcs8KeySpec = encPrivInfo.getKeySpec(cipher)
575
+ #privKeyParam = Java::OrgBouncycastleCryptoUtil::PrivateKeyFactory::createKey(pkcs8KeySpec)
344
576
  else
345
- keySpec = java.security.spec.PKCS8EncodedKeySpec.new(obj.getPrivateKeyInfo.encoded)
346
- # Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm
347
- # OID and use that to construct a KeyFactory.
348
- bIn = org.bouncycastle.asn1.ASN1InputStream.new(java.io.ByteArrayInputStream.new(keySpec.getEncoded()));
349
- pki = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(bIn.readObject());
350
- algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
351
- java.security.KeyFactory.getInstance(algOid,prov).generatePrivate(keySpec);
577
+ pkcs8KeySpec = java.security.spec.PKCS8EncodedKeySpec.new(econt)
578
+ end
579
+
580
+ key = org.bouncycastle.crypto.util.PrivateKeyFactory::createKey(java.io.ByteArrayInputStream.new(pkcs8KeySpec.getEncoded))
581
+ keyType = KeyPair.key_type(key)
582
+ case keyType
583
+ when Pkernel::KeyPair::RSA_KEY_NAME
352
584
 
353
- #privKey = java.security.KeyFactory.getInstance("RSA").generatePrivate(keySpec)
354
- #privKey
585
+ if prov.nil?
586
+ keyFact = Java::JavaSecurity::KeyFactory.getInstance("RSA")
587
+ else
588
+ keyFact = Java::JavaSecurity::KeyFactory.getInstance("RSA",prov)
589
+ end
590
+ #privKey = keyFact.generatePrivate(pkcs8KeySpec)
591
+ ## here is how to convert into RSAPublicKey, become keypair!
592
+ #pubKeySpec = Java::JavaSecuritySpec::RSAPublicKeySpec.new(privKey.getModulus(),privKey.getPublicExponent())
593
+ #pubKey = keyFact.generatePublic(pubKeySpec)
594
+
595
+ #Java::JavaSecurity::KeyPair.new(pubKey,privKey)
596
+
597
+ when Pkernel::KeyPair::DSA_KEY_NAME
598
+
599
+ if prov.nil?
600
+ keyFact = Java::JavaSecurity::KeyFactory.getInstance("DSA")
601
+ else
602
+ keyFact = Java::JavaSecurity::KeyFactory.getInstance("DSA",prov)
603
+ end
604
+
605
+ when Pkernel::KeyPair::EC_KEY_NAME
606
+
607
+ if prov.nil?
608
+ keyFact = Java::JavaSecurity::KeyFactory.getInstance("EC")
609
+ else
610
+ keyFact = Java::JavaSecurity::KeyFactory.getInstance("EC",prov)
611
+ end
612
+
613
+ else
614
+
615
+ raise PkernelJce::Error, "Unknown key type #{keyType}"
616
+
355
617
  end
618
+
619
+ privKey = keyFact.generatePrivate(pkcs8KeySpec)
620
+ ## here is how to convert into RSAPublicKey, become keypair!
621
+ #pubKeySpec = Java::JavaSecuritySpec::RSAPublicKeySpec.new(privKey.getModulus(),privKey.getPublicExponent())
622
+ #pubKey = keyFact.generatePublic(pubKeySpec)
623
+
624
+ #pubKey = PkernelJce::KeyPair.public_key(privKey)
625
+ #Java::JavaSecurity::KeyPair.new(pubKey,privKey)
626
+
627
+ privKey
628
+
629
+
630
+ #if key.java_kind_of? org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters
631
+ # keyFact = Java::JavaSecurity::KeyFactory.getInstance("RSA")
632
+ # privKey = keyFact.generatePrivate(pkcs8KeySpec)
633
+ # # here is how to convert into RSAPublicKey, become keypair!
634
+ # pubKeySpec = Java::JavaSecuritySpec::RSAPublicKeySpec.new(privKey.getModulus(),privKey.getPublicExponent())
635
+ # pubKey = keyFact.generatePublic(pubKeySpec)
636
+
637
+ # Java::JavaSecurity::KeyPair.new(pubKey,privKey)
638
+ #else
639
+ # raise PkernelJce::Error, "Unsupported PKCS8 store of type #{key}"
640
+ #end
641
+
642
+ # BC API
643
+ #reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.ByteArrayInputStream.new(baos.toByteArray)))
644
+ #obj = reader.readObject
645
+ ##p obj.inspect
646
+ ##p obj.methods.sort
647
+ ##p obj.java_kind_of?(org.bouncycastle.openssl.PEMEncryptedKeyPair)
648
+ #if obj.is_a?(org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo)
649
+ # pass = opts[:password]
650
+ # if pass.nil?
651
+ # if block
652
+ # pass = block.call(:password)
653
+ # else
654
+ # raise PkernelJce::Error, "PEM key is encrypted. Please provide a password to load the key."
655
+ # end
656
+ # end
657
+ # decProv = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder.new.setProvider(PkernelJce::Provider::DefProvider).build(pass.to_java.toCharArray)
658
+ # keyinfo = obj.decryptPrivateKeyInfo(decProv)
659
+
660
+ # converter = org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new
661
+ # converter.getPrivateKey(keyinfo)
662
+ #else
663
+ # keySpec = java.security.spec.PKCS8EncodedKeySpec.new(obj.getPrivateKeyInfo.encoded)
664
+ # # Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm
665
+ # # OID and use that to construct a KeyFactory.
666
+ # bIn = org.bouncycastle.asn1.ASN1InputStream.new(java.io.ByteArrayInputStream.new(keySpec.getEncoded()));
667
+ # pki = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(bIn.readObject());
668
+ # algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
669
+ # java.security.KeyFactory.getInstance(algOid,prov).generatePrivate(keySpec);
670
+ #
671
+ # #privKey = java.security.KeyFactory.getInstance("RSA").generatePrivate(keySpec)
672
+ # #privKey
673
+ #end
356
674
 
357
675
  end
358
676
  # end load()