ccrypto-java 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.java-version +1 -1
  3. data/.release_history.yml +4 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +68 -53
  7. data/Rakefile +2 -1
  8. data/bin/console +14 -0
  9. data/jars/bcjmail-jdk18on-172.jar +0 -0
  10. data/jars/bcmail-jdk18on-172.jar +0 -0
  11. data/jars/bcpg-jdk18on-172.1.jar +0 -0
  12. data/jars/bcpkix-jdk18on-172.jar +0 -0
  13. data/jars/bcprov-ext-jdk18on-172.jar +0 -0
  14. data/jars/bcprov-jdk18on-172.jar +0 -0
  15. data/jars/bctls-jdk18on-172.jar +0 -0
  16. data/jars/bcutil-jdk18on-172.jar +0 -0
  17. data/lib/ccrypto/java/bc_const_mapping.rb +42 -0
  18. data/lib/ccrypto/java/data_conversion.rb +23 -2
  19. data/lib/ccrypto/java/engines/argon2_engine.rb +95 -0
  20. data/lib/ccrypto/java/engines/asn1_engine.rb +2 -1
  21. data/lib/ccrypto/java/engines/bcrypt_engine.rb +56 -0
  22. data/lib/ccrypto/java/engines/cipher_engine.rb +462 -130
  23. data/lib/ccrypto/java/engines/compression_engine.rb +7 -28
  24. data/lib/ccrypto/java/engines/crystal_dilithium_engine.rb +226 -0
  25. data/lib/ccrypto/java/engines/crystal_kyber_engine.rb +260 -0
  26. data/lib/ccrypto/java/engines/decompression_engine.rb +5 -4
  27. data/lib/ccrypto/java/engines/digest_engine.rb +221 -139
  28. data/lib/ccrypto/java/engines/ecc_engine.rb +249 -96
  29. data/lib/ccrypto/java/engines/ed25519_engine.rb +211 -0
  30. data/lib/ccrypto/java/engines/hkdf_engine.rb +82 -23
  31. data/lib/ccrypto/java/engines/hmac_engine.rb +98 -23
  32. data/lib/ccrypto/java/engines/pbkdf2_engine.rb +82 -33
  33. data/lib/ccrypto/java/engines/pkcs7_engine.rb +44 -33
  34. data/lib/ccrypto/java/engines/rsa_engine.rb +85 -31
  35. data/lib/ccrypto/java/engines/scrypt_engine.rb +12 -3
  36. data/lib/ccrypto/java/engines/secret_key_engine.rb +77 -12
  37. data/lib/ccrypto/java/engines/secret_sharing_engine.rb +17 -2
  38. data/lib/ccrypto/java/engines/x25519_engine.rb +249 -0
  39. data/lib/ccrypto/java/engines/x509_csr_engine.rb +141 -0
  40. data/lib/ccrypto/java/engines/x509_engine.rb +365 -71
  41. data/lib/ccrypto/java/ext/secret_key.rb +37 -25
  42. data/lib/ccrypto/java/ext/x509_cert.rb +429 -5
  43. data/lib/ccrypto/java/ext/x509_csr.rb +151 -0
  44. data/lib/ccrypto/java/jce_provider.rb +0 -11
  45. data/lib/ccrypto/java/keystore/jce_keystore.rb +205 -0
  46. data/lib/ccrypto/java/keystore/jks_keystore.rb +52 -0
  47. data/lib/ccrypto/java/keystore/keystore.rb +97 -0
  48. data/lib/ccrypto/java/keystore/pem_keystore.rb +147 -0
  49. data/lib/ccrypto/java/keystore/pkcs12_keystore.rb +56 -0
  50. data/lib/ccrypto/java/utils/comparator.rb +25 -2
  51. data/lib/ccrypto/java/version.rb +1 -1
  52. data/lib/ccrypto/java.rb +46 -0
  53. data/lib/ccrypto/provider.rb +139 -3
  54. metadata +40 -24
  55. data/ccrypto-java.gemspec +0 -44
  56. data/jars/bcmail-jdk15on-165.jar +0 -0
  57. data/jars/bcpg-jdk15on-165.jar +0 -0
  58. data/jars/bcpkix-jdk15on-165.jar +0 -0
  59. data/jars/bcprov-ext-jdk15on-165.jar +0 -0
  60. data/jars/bcprov-jdk15on-165.jar +0 -0
  61. data/jars/bctls-jdk15on-165.jar +0 -0
  62. data/lib/ccrypto/java/keybundle_store/pkcs12.rb +0 -125
@@ -1,12 +1,11 @@
1
1
 
2
2
  require_relative '../data_conversion'
3
- require_relative '../keybundle_store/pkcs12'
4
- #require_relative '../keybundle_store/pem_store'
5
3
 
6
4
  module Ccrypto
7
5
  module Java
8
6
 
9
7
  class RSAPublicKey < Ccrypto::RSAPublicKey
8
+ include DataConversion
10
9
 
11
10
  def to_bin
12
11
  @native_pubKey.encoded
@@ -17,19 +16,87 @@ module Ccrypto
17
16
  RSAPublicKey.new(pubKey)
18
17
  end
19
18
 
19
+ def to_pem
20
+ cont = ["-----BEGIN RSA PUBLIC KEY-----\n"]
21
+ cont << to_b64(to_bin)
22
+ cont << "\n-----END RSA PUBLIC KEY-----"
23
+ cont.join
24
+ end
25
+
26
+ def self.from_pem(str)
27
+ if str =~ /RSA PUBLIC/
28
+ cont = str.lines[1..-2].join.strip
29
+ to_key(from_b64(cont))
30
+ else
31
+ raise KeypairEngineException, "Not an RSA public key"
32
+ end
33
+ end
34
+
20
35
  def method_missing(mtd, *args, &block)
21
36
  @native_pubKey.send(mtd, *args, &block)
22
37
  end
23
38
 
24
39
  end # RSAPublicKey
25
40
 
41
+
42
+ class RSAPrivateKey < Ccrypto::RSAPrivateKey
43
+ include DataConversion
44
+
45
+ def self.to_key(bin, &block)
46
+ if block
47
+ prov = block.call(:jce_provider)
48
+ else
49
+ prov = JCEProvider::BCProv
50
+ end
51
+
52
+ kf = java.security.KeyFactory.getInstance("RSA",prov)
53
+ priv = kf.generate_private(java.security.spec.PKCS8EncodedKeySpec.new(bin))
54
+ RSAPrivateKey.new(priv)
55
+
56
+ end
57
+
58
+ def to_pem
59
+ cont = ["-----BEGIN RSA PRIVATE KEY-----\n"]
60
+ cont << to_b64(@native_privKey.encoded)
61
+ cont << "\n-----END RSA PRIVATE KEY-----"
62
+ cont.join
63
+ end
64
+
65
+ def self.from_pem(str)
66
+ if str =~ /RSA PRIVATE/
67
+ cont = str.lines[1..-2].join.strip
68
+ to_key(from_b64(cont))
69
+ else
70
+ raise KeypairEngineException, "Not an RSA private key"
71
+ end
72
+ end
73
+
74
+ def to_bin
75
+ @native_privKey.encoded
76
+ end
77
+
78
+ def equals?(privKey)
79
+ if not @native_privKey.nil?
80
+ case privKey
81
+ when RSAPrivateKey
82
+ @native_privKey.encoded == privKey.to_bin
83
+ else
84
+ logger.warn "Unmatched private key : (native) #{@native_privKey} vs. (subject) #{privKey}"
85
+ false
86
+ end
87
+ else
88
+ logger.warn "RSAPrivateKey equals? returned false because native_privKey is nil"
89
+ false
90
+ end
91
+ end
92
+ alias_method :key_equals?, :equals?
93
+
94
+ end # class RSAPrivateKey
95
+
26
96
  class RSAKeyBundle
27
97
  include Ccrypto::RSAKeyBundle
28
98
  include TR::CondUtils
29
99
 
30
- include PKCS12
31
- #include PEMStore
32
-
33
100
  include TeLogger::TeLogHelper
34
101
 
35
102
  teLogger_tag :j_rsa_keybundle
@@ -52,11 +119,11 @@ module Ccrypto
52
119
  @privKey
53
120
  end
54
121
 
55
- def to_storage(type, &block)
56
-
57
- case type
58
- when :p12, :pkcs12
59
- to_pkcs12 do |key|
122
+ def write_keystore(type, &block)
123
+ ksType = Keystore.map_keystore_type(type)
124
+ case ksType
125
+ when :pkcs12
126
+ Keystore::PKCS12Keystore.to_p12 do |key, *val|
60
127
  case key
61
128
  when :keypair
62
129
  @nativeKeypair
@@ -64,43 +131,26 @@ module Ccrypto
64
131
  block.call(key) if block
65
132
  end
66
133
  end
67
-
68
134
  when :jks
69
- to_pkcs12 do |key|
135
+ Keystore::JKSKeystore.to_jks do |key, *val|
70
136
  case key
71
- when :storeType
72
- "JKS"
73
137
  when :keypair
74
138
  @nativeKeypair
75
139
  else
76
140
  block.call(key) if block
77
141
  end
78
142
  end
79
- end
80
-
81
- end
82
143
 
83
- def self.from_storage(bin, &block)
84
-
85
- if is_pem?(bin)
86
144
  else
87
- from_pkcs12(bin, &block)
88
- end
89
-
90
- end
91
-
92
- def self.is_pem?(bin)
93
- begin
94
- (bin =~ /BEGIN/) != nil
95
- rescue ArgumentError => ex
96
- false
145
+ raise Ccrypto::Keystore::KeystoreException, "Unsupported keystore type '#{type}' for engine '#{self.class.name}'"
97
146
  end
98
147
  end
99
148
 
149
+
100
150
  def equal?(kp)
101
151
  case kp
102
152
  when Ccrypto::RSAKeyBundle
103
- @nativeKeypair.encoded == kp.private.encoded
153
+ private_key.encoded == kp.private_key.encoded
104
154
  else
105
155
  false
106
156
  end
@@ -126,6 +176,10 @@ module Ccrypto
126
176
 
127
177
  teLogger_tag :j_rsa
128
178
 
179
+ def self.supported_params
180
+ [1024,2048,4096,8192]
181
+ end
182
+
129
183
  def initialize(*args, &block)
130
184
  @config = args.first
131
185
  raise KeypairEngineException, "1st parameter must be a #{Ccrypto::KeypairConfig.class} object" if not @config.is_a?(Ccrypto::KeypairConfig)
@@ -8,18 +8,22 @@ module Ccrypto
8
8
  include TR::CondUtils
9
9
 
10
10
  def initialize(conf, &block)
11
+
11
12
  raise KDFEngineException, "KDF config is expected" if not conf.is_a?(Ccrypto::KDFConfig)
12
13
  raise KDFEngineException, "Output bit length (outBitLength) value is not given or not a positive value (#{conf.outBitLength})" if is_empty?(conf.outBitLength) or conf.outBitLength <= 0
13
14
  @config = conf
14
15
 
15
16
  if is_empty?(@config.salt)
16
- @config.salt = Java::byte[16].new
17
- java.security.SecureRandom.getInstance("NativePRNG").random_bytes(@config.salt)
17
+ @config.salt = ::Java::byte[16].new
18
+ java.security.SecureRandom.getInstance("NativePRNG").next_bytes(@config.salt)
18
19
  end
19
20
  end
20
21
 
21
22
  def derive(input, output = :binary)
22
- res = org.bouncycastle.crypto.generators.SCrypt.generate(to_java_bytes(input), to_java_bytes(@config.salt),@config.cost, @config.blockSize, @config.parallel, @config.outBitLength/8)
23
+ res = org.bouncycastle.crypto.generators.SCrypt.generate(to_java_bytes(input), to_java_bytes(@config.salt),@config.cost, @config.blocksize, @config.parallel, @config.outBitLength/8)
24
+
25
+ #logger.debug "scrypt output : #{res.inspect}"
26
+
23
27
  case output
24
28
  when :hex
25
29
  to_hex(res)
@@ -30,6 +34,11 @@ module Ccrypto
30
34
  end
31
35
  end
32
36
 
37
+ private
38
+ def logger
39
+ Ccrypto::Java.logger(:scrypt_eng)
40
+ end
41
+
33
42
  end
34
43
  end
35
44
  end
@@ -2,41 +2,106 @@
2
2
 
3
3
  module Ccrypto
4
4
  module Java
5
+
6
+ class SecretKeyEngineException < StandardError; end
7
+
5
8
  class SecretKeyEngine
9
+ include TR::CondUtils
10
+ include DataConversion
11
+
12
+ def self.supported_secret_key_configs
13
+ if @supKeyConf.nil?
14
+ @supKeyConf = []
15
+ supported_secret_key_config_table.each do |algo, keysize|
16
+ keysize.each do |k,v|
17
+ @supKeyConf << v
18
+ end
19
+ end
20
+ end
21
+ @supKeyConf
22
+ end
23
+
24
+ def self.find_supported_secret_key_config(algo, keysize = nil)
25
+ res = supported_secret_key_config_table[algo] || {}
26
+ res[keysize] || nil
27
+ end
28
+
29
+ def self.is_secret_key_config_supported?(algo, keysize = nil)
30
+ not find_supported_secret_key_config(algo. keysize).nil?
31
+ end
32
+
33
+ private
34
+ def self.supported_secret_key_config_table
35
+ if @seckey_configs.nil?
36
+ @seckey_configs = {}
6
37
 
7
- include TeLogger::TeLogHelper
8
- teLogger_tag :j_secretkey
9
-
38
+ CipherEngine.supported_ciphers.each do |cf|
39
+ kf = cf.key_config
40
+ algo = kf.algo.to_sym
41
+ keysize = kf.keysize
42
+
43
+ if @seckey_configs[algo].nil?
44
+ @seckey_configs[algo] = { }
45
+ @seckey_configs[algo][keysize] = kf
46
+ else
47
+ if is_empty?(@seckey_configs[algo][keysize])
48
+ @seckey_configs[algo][keysize] = kf
49
+ end
50
+ end
51
+
52
+ end
53
+ end
54
+ @seckey_configs
55
+ end
56
+
57
+ public
10
58
  def self.generate(*args, &block)
11
59
  config = args.first
12
60
 
13
- raise SecretKeyEngineException, "KeyConfig is expected" if not config.is_a?(Ccrypto::KeyConfig)
61
+ raise SecretKeyEngineException, "KeyConfig is expected but got '#{config.class.name}'" if not config.is_a?(Ccrypto::KeyConfig)
62
+ raise SecretKeyEngineException, "Provider initialized KeyConfig is expected" if is_empty?(config.provider_config)
14
63
 
15
64
  if block
16
65
  kgProv = block.call(:keygen_jceProvider)
17
66
  ranProv = block.call(:random_jceProvider)
67
+ else
68
+ kgProv = config.provider_config[:key_jce_provider] || JCEProvider::DEFProv
18
69
  end
19
70
 
20
71
  if kgProv.nil?
21
- teLogger.debug "KeyGen using algo #{config.algo.to_s} with null provider"
22
- keyGen = javax.crypto.KeyGenerator.getInstance(config.algo.to_s)
72
+ logger.debug "KeyGen using algo #{config.algo.to_s} with null provider"
73
+ keyGen = javax.crypto.KeyGenerator.getInstance(config.provider_config[:keygen_algo])
23
74
  else
24
- teLogger.debug "KeyGen using algo #{config.algo.to_s} with provider #{kgProv.is_a?(String) ? kgProv : kgProv.name}"
25
- keyGen = javax.crypto.KeyGenerator.getInstance(config.algo.to_s, kgProv)
75
+ logger.debug "KeyGen using algo #{config.algo.to_s} with provider #{kgProv.is_a?(String) ? kgProv : kgProv.name}"
76
+ keyGen = javax.crypto.KeyGenerator.getInstance(config.provider_config[:keygen_algo], kgProv)
26
77
  end
27
78
 
28
79
  if ranProv.nil?
29
- teLogger.debug "Init KeyGen with keysize #{config.keysize.to_i}"
80
+ logger.debug "Init KeyGen with keysize #{config.keysize.to_i}"
30
81
  keyGen.init(config.keysize.to_i)
31
82
  else
32
- teLogger.debug "Init KeyGen with keysize #{config.keysize.to_i} with provider #{ranProv.is_a?(String) ? ranProv : ranProv.name}"
83
+ logger.debug "Init KeyGen with keysize #{config.keysize.to_i} with provider #{ranProv.is_a?(String) ? ranProv : ranProv.name}"
33
84
  keyGen.init(config.keysize.to_i, ranProv)
34
85
  end
35
86
 
36
87
  key = keyGen.generateKey
37
- teLogger.debug "Secret key #{config} generated"
38
- Ccrypto::SecretKey.new(config.algo, key)
88
+ logger.debug "Secret key #{config} generated"
89
+ sk = Ccrypto::SecretKey.new(config.algo, config.keysize, key)
90
+ sk.provider_config = config.provider_config
91
+ sk
92
+
93
+ end
94
+
95
+ def self.secret_key_from_bin(bin, algo, keysize)
96
+ raise SecretKeyEngineException, "No data given to convert to secret key" if is_empty?(bin)
97
+ raise SecretKeyEngineException, "Algo cannot be empty" if is_empty?(algo)
98
+
99
+ Ccrypto::SecretKey.new(algo, keysize, javax.crypto.spec.SecretKeySpec.new(to_java_bytes(bin), algo.to_s))
100
+ end
39
101
 
102
+ private
103
+ def self.logger
104
+ Ccrypto::Java.logger(:seckey_eng)
40
105
  end
41
106
 
42
107
  end
@@ -3,14 +3,22 @@ require_relative '../data_conversion'
3
3
 
4
4
  module Ccrypto
5
5
  module Java
6
+
7
+ class SecretSharingException < Ccrypto::SecretSharingException; end
8
+
6
9
  class SecretSharingEngine
7
10
  include DataConversion
8
11
 
12
+
9
13
  def initialize(*args, &block)
10
14
  @config = args.first
15
+
11
16
  raise SecretSharingException, "SecretSharingConfig is required" if not @config.is_a?(Ccrypto::SecretSharingConfig)
12
- raise SecretSharingException, "split_into value must be more than 1" if not @config.split_into.to_i > 1
13
- raise SecretSharingException, "required_parts value (#{@config.required_parts}) must be less than or equal split_into value (#{@config.split_into})." if not @config.required_parts.to_i < @config.split_into.to_i
17
+ sit = @config.split_into.to_i
18
+ rp = @config.required_parts.to_i
19
+ raise SecretSharingException, "split_into value must be more than 1" if not sit > 1
20
+ raise SecretSharingException, "required_parts value must be more than 0" if not rp > 0
21
+ raise SecretSharingException, "required_parts value (#{@config.required_parts}) must be less than or equal split_into value (#{@config.split_into})." if not rp <= sit.to_i
14
22
  end
15
23
 
16
24
  def split(secVal)
@@ -36,6 +44,7 @@ module Ccrypto
36
44
  # as the automated conversion of JRuby will turn the key into
37
45
  # java.lang.Long instead of java.lang.Integer
38
46
  # Using Map with parameterize auto conversion will failed inside the Java
47
+ partLength = -1
39
48
  parts.each do |k,v|
40
49
  if not v.is_a?(::Java::byte[])
41
50
  vv = to_java_bytes(v)
@@ -43,6 +52,12 @@ module Ccrypto
43
52
  vv = v
44
53
  end
45
54
 
55
+ if partLength == -1
56
+ partLength = vv.length
57
+ else
58
+ raise SecretSharingException, "Invalid parts are given. Inconsistant part length (#{partLength} vs. #{vv.length})" if partLength != vv.length
59
+ end
60
+
46
61
  jhash.put(java.lang.Integer.new(k),vv)
47
62
  end
48
63
  when java.util.Map
@@ -0,0 +1,249 @@
1
+
2
+ require_relative '../data_conversion'
3
+
4
+ module Ccrypto
5
+ module Java
6
+
7
+ class X25519PublicKey < Ccrypto::X25519PublicKey
8
+ include DataConversion
9
+
10
+ def to_bin
11
+ res = @native_pubKey.encoded
12
+ #puts "to_bion : #{to_hex(res)}"
13
+ res
14
+ end
15
+
16
+ def self.to_key(bin)
17
+ pubKey = java.security.KeyFactory.getInstance("X25519", "BC").generatePublic(java.security.spec.X509EncodedKeySpec.new(bin))
18
+ X25519PublicKey.new(pubKey)
19
+ end
20
+
21
+ def to_pem
22
+ cont = ["-----BEGIN X25519 PUBLIC KEY-----\n"]
23
+ cont << to_b64(to_bin)
24
+ cont << "\n-----END X25519 PUBLIC KEY-----"
25
+ cont.join
26
+ end
27
+
28
+ def self.from_pem(str)
29
+ if str =~ /X25519 PUBLIC/
30
+ cont = str.lines[1..-2].join.strip
31
+ to_key(from_b64(cont))
32
+ else
33
+ raise KeypairEngineException, "Not an X25519 public key"
34
+ end
35
+ end
36
+
37
+ end # X25519PublicKey
38
+
39
+ class X25519PrivateKey < Ccrypto::X25519PrivateKey
40
+ include DataConversion
41
+
42
+ def to_bin
43
+ @native_privKey.encoded
44
+ end
45
+
46
+ def self.to_key(bin, &block)
47
+ if block
48
+ prov = block.call(:jce_provider)
49
+ else
50
+ prov = JCEProvider::BCProv
51
+ end
52
+
53
+ kf = java.security.KeyFactory.getInstance("X25519",prov)
54
+ priv = kf.generate_private(java.security.spec.PKCS8EncodedKeySpec.new(bin))
55
+ X25519PrivateKey.new(priv)
56
+
57
+ end
58
+
59
+ def to_pem
60
+ cont = ["-----BEGIN X25519 PRIVATE KEY-----\n"]
61
+ cont << to_b64(@native_privKey.encoded)
62
+ cont << "\n-----END X25519 PRIVATE KEY-----"
63
+ cont.join
64
+ end
65
+
66
+ def self.from_pem(str)
67
+ if str =~ /X25519 PRIVATE/
68
+ cont = str.lines[1..-2].join.strip
69
+ to_key(from_b64(cont))
70
+ else
71
+ raise KeypairEngineException, "Not an X25519 private key"
72
+ end
73
+ end
74
+
75
+ def equals?(privKey)
76
+ if not @native_privKey.nil?
77
+ case privKey
78
+ when X25519PrivateKey
79
+ @native_privKey.encoded == privKey.to_bin
80
+ else
81
+ logger.warn "Unmatched private key : (native) #{@native_privKey} vs. (subject) #{privKey}"
82
+ false
83
+ end
84
+ else
85
+ logger.warn "X25519PrivateKey equals? returned false because native_privKey is nil"
86
+ false
87
+ end
88
+ end
89
+ alias_method :key_equals?, :equals?
90
+
91
+ end # X25519PrivateKey
92
+
93
+ class X25519KeyBundle
94
+ include Ccrypto::X25519KeyBundle
95
+ include Ccrypto::X25519KeyBundle
96
+
97
+ include TR::CondUtils
98
+ include DataConversion
99
+
100
+ include TeLogger::TeLogHelper
101
+ teLogger_tag :x25519_kb_j
102
+
103
+ def initialize(kp)
104
+ @nativeKeypair = kp
105
+ end
106
+
107
+ def public_key
108
+ if @pubKey.nil?
109
+ @pubKey = X25519PublicKey.new(@nativeKeypair.getPublic)
110
+ end
111
+ @pubKey
112
+ end
113
+
114
+ def private_key
115
+ X25519PrivateKey.new(@nativeKeypair.getPrivate)
116
+ end
117
+
118
+ def derive_dh_shared_secret(pubKey, &block)
119
+
120
+ JCEProvider.instance.add_bc_provider
121
+
122
+ ka = javax.crypto.KeyAgreement.getInstance("X25519",JCEProvider::BCProv.name)
123
+ ka.init(@nativeKeypair.getPrivate)
124
+
125
+ case pubKey
126
+ when X25519PublicKey
127
+ uPubKey = pubKey.native_pubKey
128
+ else
129
+ raise KeypairEngineException, "Unsupported public key type '#{pubKey.class}'"
130
+ end
131
+
132
+ ka.doPhase(uPubKey, true)
133
+ ka.generateSecret()
134
+
135
+ end
136
+
137
+ ## should be under keybundle_store but not sure how to do this
138
+ def to_storage(eng = :ccrypto, &block)
139
+ case eng
140
+ when :ccrypto
141
+ res = { }
142
+
143
+ rawPrivate = false
144
+ rawPublic = false
145
+ if block
146
+ rawPrivate = block.call(:export_raw_private_key)
147
+ rawPublic = block.call(:export_raw_public_key)
148
+ end
149
+
150
+ res[:private] = private_key.to_bin
151
+ if rawPrivate == true
152
+ # 5th Sept 2022 - untested code
153
+ res[:private] = org.bouncycastle.crypto.params.X25519PrivateKeyParameters.new(res[:private],0).encoded
154
+ res[:raw_private] = true
155
+ end
156
+
157
+ res[:public] = public_key.to_bin
158
+ if rawPublic == true
159
+ # 5th Sept 2022 - untested code
160
+ res[:public] = org.bouncycastle.crypto.params.X25519PublicKeyParameters.new(res[:public],0).encoded
161
+ res[:raw_public] = true
162
+ end
163
+
164
+ res
165
+ else
166
+ raise KeypairEngineException, "Unsupported storage type '#{eng}'"
167
+ end
168
+ end
169
+
170
+ def self.from_storage(bin)
171
+ case bin
172
+ when Hash
173
+ res = { }
174
+ JCEProvider.instance.add_bc_provider
175
+
176
+ kf = java.security.KeyFactory.getInstance("X25519", JCEProvider::BCProv.name)
177
+
178
+ if not_empty?(bin[:private])
179
+ # raw_private = true means the given private key is in its raw data form
180
+ # 5th Sept 22 - Not tested not sure how to generate raw key
181
+ if bin[:raw_private] == true
182
+ # 5th Sept 2022 - untested code
183
+ info = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.new(org.bouncycastle.asn1.x509.AlgorithmIdentifier.new(org.bouncycastle.asn1.edec.EdECObjectIdentifiers::id_X25519), org.bouncycastle.asn1.DEROctetString.new(bin[:private]))
184
+
185
+ spec = java.security.spec.PKCS8EncodedKeySpec.new(info.encoded)
186
+ else
187
+ spec = java.security.spec.PKCS8EncodedKeySpec.new(bin[:private])
188
+ end
189
+
190
+ res[:private] = X25519PrivateKey.new(kf.generatePrivate(spec))
191
+
192
+ #res[:private] = X25519PrivateKey.new(org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters.new(bin[:private],0))
193
+ end
194
+
195
+ if not_empty?(bin[:public])
196
+ if bin[:raw_public] == true
197
+ # 5th Sept 2022 - untested code
198
+ #pubRaw = org.bouncycastle.crypto.params.Ed25519PublicKeyParameters.new(bin[:public],0).encoded
199
+ pubRaw = bin[:public]
200
+ info = org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.new(org.bouncycastle.asn1.x509.AlgorithmIdentifier.new(org.bouncycastle.asn1.edec.EdECObjectIdentifiers::id_X25519), bin[:public])
201
+
202
+ spec = java.security.spec.X509EncodedKeySpec.new(info.encoded)
203
+ else
204
+ spec = java.security.spec.X509EncodedKeySpec.new(bin[:public])
205
+ end
206
+
207
+ res[:public] = X25519PublicKey.new(kf.generatePublic(spec))
208
+ end
209
+
210
+ res[:keypair] = X25519KeyBundle.new(java.security.KeyPair.new(res[:public].native_pubKey, res[:private].native_privKey)) if not_empty?(res[:public]) and not_empty?(res[:private])
211
+
212
+ res
213
+
214
+ else
215
+ raise KeypairEngineException, "No sure how to handle storage input '#{bin.class}'"
216
+ end
217
+ end
218
+
219
+ end # X25519KeyBundle
220
+
221
+ class X25519Engine
222
+ include TR::CondUtils
223
+ include DataConversion
224
+
225
+ include TeLogger::TeLogHelper
226
+ teLogger_tag :x25519_eng_j
227
+
228
+ def self.supported_params
229
+ []
230
+ end
231
+
232
+ def initialize(*args, &block)
233
+ @config = args.first
234
+ end
235
+
236
+ def generate_keypair(&block)
237
+
238
+ JCEProvider.instance.add_bc_provider
239
+ kg = java.security.KeyPairGenerator.getInstance("X25519", JCEProvider::BCProv.name)
240
+ kg.java_send(:initialize, [java.security.spec.AlgorithmParameterSpec], org.bouncycastle.jcajce.spec.XDHParameterSpec.new(org.bouncycastle.jcajce.spec.XDHParameterSpec::X25519))
241
+ X25519KeyBundle.new(kg.generateKeyPair)
242
+
243
+ end
244
+
245
+
246
+ end
247
+
248
+ end
249
+ end