pkernel_jce 0.3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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()