ccrypto-java 0.1.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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.java-version +1 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +13 -0
  5. data/Gemfile.lock +94 -0
  6. data/README.md +150 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +15 -0
  9. data/bin/setup +8 -0
  10. data/ccrypto-java.gemspec +44 -0
  11. data/jars/bcmail-jdk15on-165.jar +0 -0
  12. data/jars/bcpg-jdk15on-165.jar +0 -0
  13. data/jars/bcpkix-jdk15on-165.jar +0 -0
  14. data/jars/bcprov-ext-jdk15on-165.jar +0 -0
  15. data/jars/bcprov-jdk15on-165.jar +0 -0
  16. data/jars/bctls-jdk15on-165.jar +0 -0
  17. data/jars/shamir-0.6.1-p.jar +0 -0
  18. data/lib/ccrypto/java/data_conversion.rb +80 -0
  19. data/lib/ccrypto/java/engines/asn1_engine.rb +161 -0
  20. data/lib/ccrypto/java/engines/asn1_object.rb +12 -0
  21. data/lib/ccrypto/java/engines/cipher_engine.rb +255 -0
  22. data/lib/ccrypto/java/engines/compression_engine.rb +92 -0
  23. data/lib/ccrypto/java/engines/data_conversion_engine.rb +9 -0
  24. data/lib/ccrypto/java/engines/decompression_engine.rb +48 -0
  25. data/lib/ccrypto/java/engines/digest_engine.rb +208 -0
  26. data/lib/ccrypto/java/engines/ecc_engine.rb +263 -0
  27. data/lib/ccrypto/java/engines/hkdf_engine.rb +72 -0
  28. data/lib/ccrypto/java/engines/hmac_engine.rb +75 -0
  29. data/lib/ccrypto/java/engines/pbkdf2_engine.rb +87 -0
  30. data/lib/ccrypto/java/engines/pkcs7_engine.rb +558 -0
  31. data/lib/ccrypto/java/engines/rsa_engine.rb +572 -0
  32. data/lib/ccrypto/java/engines/scrypt_engine.rb +35 -0
  33. data/lib/ccrypto/java/engines/secret_key_engine.rb +44 -0
  34. data/lib/ccrypto/java/engines/secret_sharing_engine.rb +59 -0
  35. data/lib/ccrypto/java/engines/secure_random_engine.rb +76 -0
  36. data/lib/ccrypto/java/engines/x509_engine.rb +311 -0
  37. data/lib/ccrypto/java/ext/secret_key.rb +75 -0
  38. data/lib/ccrypto/java/ext/x509_cert.rb +48 -0
  39. data/lib/ccrypto/java/jce_provider.rb +52 -0
  40. data/lib/ccrypto/java/keybundle_store/pkcs12.rb +125 -0
  41. data/lib/ccrypto/java/utils/comparator.rb +20 -0
  42. data/lib/ccrypto/java/utils/memory_buffer.rb +77 -0
  43. data/lib/ccrypto/java/utils/native_helper.rb +19 -0
  44. data/lib/ccrypto/java/version.rb +7 -0
  45. data/lib/ccrypto/java.rb +30 -0
  46. data/lib/ccrypto/provider.rb +132 -0
  47. metadata +144 -0
@@ -0,0 +1,76 @@
1
+
2
+ require_relative '../data_conversion'
3
+
4
+ module Ccrypto
5
+ module Java
6
+ class SecureRandomEngine
7
+ include TR::CondUtils
8
+ extend DataConversion
9
+
10
+
11
+ def self.random_bytes(size, &block)
12
+ buf = ::Java::byte[size].new
13
+ engine(&block).next_bytes(buf)
14
+ buf
15
+ end
16
+
17
+ def self.random_hex(size,&block)
18
+ to_hex(random_bytes(size,&block))
19
+ end
20
+
21
+ def self.random_b64(size, &block)
22
+ to_b64(random_bytes(size, &block))
23
+ end
24
+
25
+ def self.random_uuid
26
+ java.util.UUID.randomUUID.to_s
27
+ end
28
+
29
+ def self.random_alphanu(size, &block)
30
+ SecureRandom.alphanumeric(size)
31
+ end
32
+
33
+ def self.random_number(val, &block)
34
+ if val.is_a?(Range)
35
+ v = engine(&block).next_int(val.max)
36
+ if v < val.min
37
+ v = v+val.min
38
+ end
39
+ v
40
+ elsif val.is_a?(Integer)
41
+ engine(&block).next_int(val)
42
+ elsif is_empty?(val)
43
+ engine(&block).next_double
44
+ end
45
+ end
46
+
47
+
48
+ private
49
+ def self.engine(&block)
50
+ if @srEngine.nil?
51
+ srJceProvider = nil
52
+ algo = "NativePRNG"
53
+ if block
54
+ jceProv = block.call(:jce_provider)
55
+ srJceProvider = jceProv
56
+
57
+ al = block.call(:secure_random_engine_name)
58
+ algo = al if not_empty?(al)
59
+ else
60
+ algo = "NativePRNG"
61
+ end
62
+
63
+ if srJceProvider.nil?
64
+ @srEngine = java.security.SecureRandom.getInstance(algo)
65
+ else
66
+ @srEngine = java.security.SecureRandom.getInstance(algo,srJceProvider)
67
+ end
68
+ end
69
+
70
+ @srEngine
71
+ end
72
+
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,311 @@
1
+
2
+ module Ccrypto
3
+ module Java
4
+
5
+ class X509Engine
6
+ include TR::CondUtils
7
+
8
+ include TeLogger::TeLogHelper
9
+
10
+ teLogger_tag :j_x509
11
+
12
+ def initialize(certProf)
13
+ @certProfile = certProf
14
+ end
15
+
16
+ def generate(issuerKey, &block)
17
+
18
+ cp = @certProfile
19
+
20
+ raise X509EngineException, "Issuer key must be given" if issuerKey.nil?
21
+ raise X509EngineException, "Issuer key must be a private key. Given #{issuerKey}" if not issuerKey.is_a?(Ccrypto::PrivateKey)
22
+
23
+ prov = Ccrypto::Java::JCEProvider::DEFProv
24
+ signSpec = nil
25
+ if block
26
+ uprov = block.call(:jce_provider_name)
27
+ prov if not_empty?(uprov)
28
+ signSpec = block.call(:sign_spec)
29
+ signHash = block.call(:sign_hash)
30
+ end
31
+
32
+ signHash = :sha256 if is_empty?(signHash)
33
+
34
+ validFrom = cp.not_before
35
+ validTo = cp.not_after
36
+
37
+ extUtils = org.bouncycastle.cert.bc.BcX509ExtensionUtils.new
38
+
39
+ if cp.serial.is_a?(java.math.BigInteger)
40
+ serial = cp.serial
41
+ else
42
+ serial = java.math.BigInteger.new(cp.serial, 16)
43
+ end
44
+
45
+ iss = cp.issuer_cert
46
+ if not_empty?(iss)
47
+ raise X509EngineException, "Issuer certificate must be Ccrypto::X509Cert object (#{iss.class})" if not iss.is_a?(Ccrypto::X509Cert) #iss.is_a?(java.security.cert.Certificate)
48
+
49
+ certGen = org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder.new(Ccrypto::X509Cert.to_java_cert(iss), serial, validFrom, validTo, to_cert_subject, cp.public_key)
50
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(iss.getPublicKey.encoded)))
51
+
52
+ else
53
+
54
+ name = to_cert_subject
55
+ certGen = org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder.new(name, serial, validFrom, validTo, name, cp.public_key.native_pubKey)
56
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(cp.public_key.to_bin)))
57
+ end
58
+
59
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::basicConstraints, true, org.bouncycastle.asn1.x509.BasicConstraints.new(true)) if cp.gen_issuer_cert?
60
+
61
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, false, org.bouncycastle.asn1.x509.KeyUsage.new(to_keyusage))
62
+ #criticalKu = 0
63
+ #nonCriticalKu = 0
64
+ kuv = 0
65
+ criticalKu = false
66
+ cp.key_usage.selected.each do |ku, critical|
67
+ case ku
68
+ when :digitalSignature
69
+ kur = org.bouncycastle.asn1.x509::KeyUsage::digitalSignature
70
+ when :nonRepudiation
71
+ kur = org.bouncycastle.asn1.x509::KeyUsage::nonRepudiation
72
+ when :keyEncipherment
73
+ kur = org.bouncycastle.asn1.x509::KeyUsage::keyEncipherment
74
+ when :dataEncipherment
75
+ kur = org.bouncycastle.asn1.x509::KeyUsage::dataEncipherment
76
+ when :keyAgreement
77
+ kur = org.bouncycastle.asn1.x509::KeyUsage::keyAgreement
78
+ when :keyCertSign
79
+ kur = org.bouncycastle.asn1.x509::KeyUsage::keyCertSign
80
+ when :crlSign
81
+ kur = org.bouncycastle.asn1.x509::KeyUsage::cRLSign
82
+ when :encipherOnly
83
+ kur = org.bouncycastle.asn1.x509::KeyUsage::encipherOnly
84
+ when :decipherOnly
85
+ kur = org.bouncycastle.asn1.x509::KeyUsage::decipherOnly
86
+ end
87
+
88
+ criticalKu = critical if critical
89
+
90
+ kuv |= kur
91
+
92
+ #if critical
93
+ # criticalKu |= kur
94
+ #else
95
+ # nonCriticalKu |= kur
96
+ #end
97
+
98
+ end
99
+
100
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, criticalKu, org.bouncycastle.asn1.x509.KeyUsage.new(kuv))
101
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, true, org.bouncycastle.asn1.x509.KeyUsage.new(criticalKu)) if criticalKu != 0
102
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, false, org.bouncycastle.asn1.x509.KeyUsage.new(nonCriticalKu)) if nonCriticalKu != 0
103
+
104
+ ekuCritical = false
105
+ eku = java.util.Vector.new
106
+ #ekuCritical = java.util.Vector.new
107
+ #ekuNonCritical = java.util.Vector.new
108
+ cp.ext_key_usage.selected.each do |ku,critical|
109
+ case ku
110
+ when :allPurpose
111
+ kur = org.bouncycastle.asn1.x509.KeyPurposeId::anyExtendedKeyUsage
112
+ when :serverAuth
113
+ kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_serverAuth
114
+ when :clientAuth
115
+ kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_clientAuth
116
+ when :codeSigning
117
+ kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_codeSigning
118
+ when :emailProtection
119
+ kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_emailProtection
120
+ when :timestamping
121
+ kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_timeStamping
122
+ when :ocspSigning
123
+ kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_OCSPSigning
124
+ end
125
+
126
+ ekuCritical = critical if critical
127
+ eku.add_element(kur)
128
+ #if critical
129
+ # ekuCritical.add_element(kur)
130
+ #else
131
+ # ekuNonCritical.add_element(kur)
132
+ #end
133
+ end
134
+
135
+ #extKeyUsage = java.util.Vector.new
136
+ cp.domain_key_usage.each do |dku, critical|
137
+ kur = org.bouncycastle.asn1.DERObjectIdentifier.new(dku)
138
+
139
+ ekuCritical = critical if critical
140
+ eku.add_element(kur)
141
+ #if critical
142
+ # ekuCritical.add_element(kur)
143
+ #else
144
+ # ekuNonCritical.add_element(kur)
145
+ #end
146
+ end
147
+
148
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, ekuCritical, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(eku)) if not_empty?(eku)
149
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, true, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(ekuCritical)) if not_empty?(ekuCritical)
150
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, false, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(ekuNonCritical)) if not_empty?(ekuNonCritical)
151
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, false, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(extKeyUsage)) if not extKeyUsage.is_empty?
152
+
153
+ altName = []
154
+ cp.email.each do |e|
155
+ altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::rfc822Name,e)
156
+ end
157
+
158
+ cp.dns_name.each do |d|
159
+ altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::dNSName,d)
160
+ end
161
+
162
+ cp.ip_addr.each do |d|
163
+ altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::iPAddress,d)
164
+ end
165
+
166
+ cp.uri.each do |u|
167
+ altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier,u)
168
+ end
169
+
170
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::subjectAlternativeName, false, org.bouncycastle.asn1.x509.GeneralNames.new(altName.to_java(org.bouncycastle.asn1.x509.GeneralName)) )
171
+
172
+ if not_empty?(cp.crl_dist_point)
173
+ crls = []
174
+ cp.crl_dist_point.each do |c|
175
+ crls << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier, org.bouncycastle.asn1.DERIA5String.new(c))
176
+ end
177
+ gns = org.bouncycastle.asn1.x509.GeneralNames.new(crls.to_java(org.bouncycastle.asn1.x509.GeneralName))
178
+ dpn = org.bouncycastle.asn1.x509.DistributionPointName.new(gns)
179
+ dp = org.bouncycastle.asn1.x509.DistributionPoint.new(dpn,nil,nil)
180
+ certGen.addExtension(org.bouncycastle.asn1.x509.X509Extensions::CRLDistributionPoints,false,org.bouncycastle.asn1.DERSequence.new(dp))
181
+ end
182
+
183
+ aia = []
184
+ cp.ocsp_url.each do |o|
185
+ ov = org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier, org.bouncycastle.asn1.DERIA5String.new(o))
186
+ aia << org.bouncycastle.asn1.x509.AccessDescription.new(org.bouncycastle.asn1.x509.AccessDescription.id_ad_ocsp, ov)
187
+ end
188
+
189
+ cp.issuer_url.each do |i|
190
+ iv = org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier, org.bouncycastle.asn1.DERIA5String.new(i))
191
+ aia << org.bouncycastle.asn1.x509.AccessDescription.new(org.bouncycastle.asn1.x509.AccessDescription.id_ad_caIssuers, iv)
192
+ end
193
+
194
+ if not_empty?(aia)
195
+ authorityInformationAccess = org.bouncycastle.asn1.x509.AuthorityInformationAccess.new(aia.to_java(org.bouncycastle.asn1.x509.AccessDescription))
196
+ certGen.addExtension(org.bouncycastle.asn1.x509.X509Extensions::AuthorityInfoAccess, false, authorityInformationAccess)
197
+ end
198
+
199
+
200
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(cp.public_key.to_bin)))
201
+
202
+ signAlgo = nil
203
+ if is_empty?(signSpec)
204
+ gKey = issuerKey
205
+ loop do
206
+ case gKey
207
+ when org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
208
+ signAlgo = "#{signHash.to_s.upcase}WithECDSA"
209
+ break
210
+ when java.security.interfaces.RSAPrivateKey , org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey
211
+ signAlgo = "#{signHash.to_s.upcase}WithRSA"
212
+ break
213
+ when Ccrypto::PrivateKey
214
+ teLogger.debug "Found Ccrypto::Private key #{gKey}."
215
+ gKey = gKey.native_privKey
216
+ else
217
+ raise X509EngineException, "Unsupported issuer key type '#{gKey}'"
218
+ end
219
+ end
220
+ else
221
+ end
222
+
223
+ #signAlgo = "SHA256WithECDSA"
224
+ #signer = org.bouncycastle.operator.jcajce.JcaContentSignerBuilder.new(signAlgo).setProvider(prov).build(issuerKey.private_key)
225
+ signer = org.bouncycastle.operator.jcajce.JcaContentSignerBuilder.new(signAlgo).setProvider(prov).build(gKey)
226
+
227
+ cert = org.bouncycastle.cert.jcajce.JcaX509CertificateConverter.new().setProvider(prov).getCertificate(certGen.build(signer))
228
+ cert
229
+
230
+ Ccrypto::X509Cert.new(cert)
231
+
232
+ end
233
+
234
+ def to_cert_subject
235
+
236
+ builder = org.bouncycastle.asn1.x500.X500NameBuilder.new
237
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::CN, @certProfile.owner_name)
238
+
239
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::O, @certProfile.org) if not_empty?(@certProfile.org)
240
+
241
+ @certProfile.org_unit.each do |ou|
242
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::OU, ou)
243
+ end
244
+
245
+ #builder.addRDN(Java::OrgBouncycastleAsn1X500Style::BCStyle::SN, serial) if @serial != nil and not @serial.empty?
246
+
247
+ e = @certProfile.email.first
248
+ if not_empty?(e)
249
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::EmailAddress, e)
250
+ end
251
+
252
+ builder.build
253
+
254
+ end
255
+
256
+ #def to_keyusage
257
+ # kur = 0
258
+ # @certProfile.key_usage.selected.each do |ku|
259
+ # case ku
260
+ # when :digitalSignature
261
+ # kur |= org.bouncycastle.asn1.x509::KeyUsage::digitalSignature
262
+ # when :nonRepudiation
263
+ # kur |= org.bouncycastle.asn1.x509::KeyUsage::nonRepudiation
264
+ # when :keyEncipherment
265
+ # kur |= org.bouncycastle.asn1.x509::KeyUsage::keyEncipherment
266
+ # when :dataEncipherment
267
+ # kur |= org.bouncycastle.asn1.x509::KeyUsage::dataEncipherment
268
+ # when :keyAgreement
269
+ # kur |= org.bouncycastle.asn1.x509::KeyUsage::keyAgreement
270
+ # when :keyCertSign
271
+ # kur |= org.bouncycastle.asn1.x509::KeyUsage::keyCertSign
272
+ # when :crlSign
273
+ # kur |= org.bouncycastle.asn1.x509::KeyUsage::cRLSign
274
+ # when :encipherOnly
275
+ # kur |= org.bouncycastle.asn1.x509::KeyUsage::encipherOnly
276
+ # when :decipherOnly
277
+ # kur |= org.bouncycastle.asn1.x509::KeyUsage::decipherOnly
278
+ # end
279
+ # end
280
+
281
+ # kur
282
+ #end
283
+
284
+ def to_extkeyusage
285
+ kur = java.util.Vector.new
286
+ @certProfile.ext_key_usage.selected.each do |ku|
287
+ case ku
288
+ when :allPurpose
289
+ kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::anyExtendedKeyUsage
290
+ when :serverAuth
291
+ kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_serverAuth
292
+ when :clientAuth
293
+ kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_clientAuth
294
+ when :codeSigning
295
+ kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_codeSigning
296
+ when :emailProtection
297
+ kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_emailProtection
298
+ when :timestamping
299
+ kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_timeStamping
300
+ when :ocspSigning
301
+ kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_OCSPSigning
302
+ end
303
+ end
304
+
305
+ kur
306
+ end
307
+
308
+ end
309
+
310
+ end
311
+ end
@@ -0,0 +1,75 @@
1
+
2
+ require_relative '../data_conversion'
3
+
4
+ module Ccrypto
5
+ class SecretKey
6
+ include Java::DataConversion
7
+
8
+ include TeLogger::TeLogHelper
9
+ teLogger_tag :j_secretkey_ext
10
+
11
+ def to_jce_secret_key
12
+ case @key
13
+ when javax.crypto.spec.SecretKeySpec
14
+ @key
15
+ when ::Java::byte[]
16
+ javax.crypto.spec.SecretKeySpec.new(@key, @algo.to_s)
17
+
18
+ else
19
+ case @key.key
20
+ when javax.crypto.spec.SecretKeySpec
21
+ @key.key
22
+ when ::Java::byte[]
23
+ javax.crypto.spec.SecretKeySpec.new(@key.key, @algo.to_s)
24
+ else
25
+ raise Ccrypto::Error, "Unknown key to conver to jce #{@key.key}"
26
+ end
27
+ end
28
+ end
29
+
30
+ def to_bin
31
+ case @key
32
+ when javax.crypto.spec.SecretKeySpec
33
+ @key.encoded
34
+ else
35
+ raise Ccrypto::Error, "Unsupported key type #{@key.class}"
36
+ end
37
+ end
38
+
39
+ def length
40
+ case @key
41
+ when javax.crypto.spec.SecretKeySpec
42
+ @key.encoded.length
43
+ when ::Java::byte[]
44
+ @key.length
45
+ else
46
+ @key.key.encoded.length
47
+ end
48
+ end
49
+
50
+ def equals?(key)
51
+ case key
52
+ when Ccrypto::SecretKey
53
+ teLogger.debug "Given key is Ccrypto::SecretKey"
54
+ to_jce_secret_key.encoded == key.to_jce_secret_key.encoded
55
+ when javax.crypto.spec.SecretKeySpec
56
+ teLogger.debug "Given key is java SecretKeySpec"
57
+ to_jce_secret_key.encoded == key.encoded
58
+ when ::Java::byte[]
59
+ to_jce_secret_key.encoded == key
60
+ when String
61
+ to_jce_secret_key.encoded == to_java_bytes(key)
62
+ else
63
+ teLogger.debug "Not sure how to compare : #{self} / #{key}"
64
+ to_jce_secret_key == key
65
+ end
66
+ end
67
+
68
+ #def each_char(&block)
69
+ # to_bin.each do |b|
70
+ # block.call(b)
71
+ # end
72
+ #end
73
+
74
+ end
75
+ end
@@ -0,0 +1,48 @@
1
+
2
+
3
+ module Ccrypto
4
+ class X509Cert
5
+ include TR::CondUtils
6
+
7
+ def to_der
8
+ @nativeX509.encoded
9
+ end
10
+
11
+ def method_missing(mtd, *args, &block)
12
+ @nativeX509.send(mtd, *args, &block)
13
+ end
14
+
15
+ def equal?(cert)
16
+ if cert.nil?
17
+ if @nativeX509.nil?
18
+ true
19
+ else
20
+ false
21
+ end
22
+ else
23
+
24
+ tcert = self.class.to_java_cert(cert)
25
+ lcert = self.class.to_java_cert(@nativeX509)
26
+
27
+ tcert.encoded == @nativeX509.encoded
28
+ end
29
+ end
30
+
31
+ def self.to_java_cert(cert)
32
+ raise X509CertException, "Given certificate to convert to Java certificate object is empty" if is_empty?(cert)
33
+
34
+ case cert
35
+ when java.security.cert.Certificate
36
+ cert
37
+ when org.bouncycastle.cert.X509CertificateHolder
38
+ cert.to_java_cert
39
+ when Ccrypto::X509Cert
40
+ to_java_cert(cert.nativeX509)
41
+ else
42
+ raise X509CertException, "Unknown certificate type #{cert} for conversion"
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,52 @@
1
+
2
+ require 'singleton'
3
+
4
+ module Ccrypto
5
+ module Java
6
+
7
+ class JCEProviderException < StandardError; end
8
+
9
+ class JCEProvider
10
+ include Singleton
11
+
12
+ BCProv = org.bouncycastle.jce.provider.BouncyCastleProvider.new
13
+ DEFProv = BCProv
14
+
15
+ def add_provider(prov = nil)
16
+ case prov
17
+ when java.security.Provider
18
+ java.security.Security.add_provider(prov) if not is_provider_registered?(prov)
19
+ else
20
+ java.security.Security.add_provider(DEFProv) if not is_provider_registered?(DEFProv)
21
+ end
22
+ end
23
+
24
+ def is_provider_registered?(prov)
25
+ case prov
26
+ when String
27
+ java.security.Security.providers.to_a.map { |v| v.name }.include?(prov)
28
+ when java.security.Provider
29
+ java.security.Security.get_providers.to_a.include?(prov)
30
+ else
31
+ false
32
+ end
33
+ end
34
+
35
+ def add_bc_provider
36
+ add_provider
37
+ end
38
+
39
+ #def set_default_provider(prov)
40
+
41
+ # case prov
42
+ # when String
43
+ # when java.security.Provider
44
+ # add_provider(prov) if not is_provider_registered?(prov)
45
+ # @defProvider = prov
46
+ # end
47
+
48
+ #end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,125 @@
1
+
2
+ require_relative '../data_conversion'
3
+
4
+ module Ccrypto
5
+ module Java
6
+
7
+ module PKCS12
8
+ include TR::CondUtils
9
+ include DataConversion
10
+
11
+ class PKCS12StorageException < KeyBundleStorageException; end
12
+
13
+ module ClassMethods
14
+ include DataConversion
15
+
16
+ def from_pkcs12(bin, &block)
17
+
18
+ raise PKCS12StorageException, "block is required" if not block
19
+
20
+ storeType = block.call(:store_type)
21
+ storeType = "PKCS12" if is_empty?(storeType)
22
+
23
+ prof = block.call(:jce_provider)
24
+ if not_empty?(prof)
25
+ ks = java.security.KeyStore.getInstance(storeType, prof)
26
+ else
27
+ ks = java.security.KeyStore.getInstance(storeType)
28
+ end
29
+
30
+ pass = block.call(:p12_pass) || block.call(:jks_pass)
31
+ name = block.call(:p12_name) || block.call(:jks_name)
32
+
33
+ #case bin
34
+ #when String
35
+ # bbin = bin.to_java_bytes
36
+ #when ::Java::byte[]
37
+ # bbin = bin
38
+ #else
39
+ # raise KeypairEngineException, "Java byte array is expected. Given #{bin.class}"
40
+ #end
41
+
42
+ bbin = to_java_bytes(bin)
43
+
44
+ ks.load(java.io.ByteArrayInputStream.new(bbin),pass.to_java.toCharArray)
45
+
46
+ name = ks.aliases.to_a.first if is_empty?(name)
47
+
48
+ userCert = Ccrypto::X509Cert.new(ks.getCertificate(name))
49
+ chain = ks.get_certificate_chain(name).collect { |c| Ccrypto::X509Cert.new(c) }
50
+ chain = chain.delete_if { |c| c.equal?(userCert) }
51
+
52
+ key = ks.getKey(name, pass.to_java.toCharArray)
53
+ case key
54
+ when java.security.interfaces.ECPrivateKey
55
+ [Ccrypto::Java::ECCKeyBundle.new(key), userCert, chain]
56
+ when java.security.interfaces.RSAPrivateKey
57
+ [Ccrypto::Java::RSAKeyBundle.new(key), userCert, chain]
58
+ else
59
+ raise PKCS12StorageException, "Unknown key type #{key}"
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ def self.included(klass)
66
+ klass.extend(ClassMethods)
67
+ end
68
+
69
+ def to_pkcs12(&block)
70
+
71
+ raise KeypairEngineException, "block is required" if not block
72
+
73
+ storeType = block.call(:store_type)
74
+ storeType = "PKCS12" if is_empty?(storeType)
75
+
76
+ prof = block.call(:jce_provider)
77
+ if not_empty?(prof)
78
+ ks = java.security.KeyStore.getInstance(storeType, prof)
79
+ else
80
+ ks = java.security.KeyStore.getInstance(storeType)
81
+ end
82
+
83
+ ks.load(nil,nil)
84
+
85
+ gcert = block.call(:cert)
86
+ raise KeypairEngineException, "PKCS12 requires the X.509 certificate" if is_empty?(gcert)
87
+
88
+ ca = block.call(:certchain) || [cert]
89
+ ca = [cert] if is_empty?(ca)
90
+ ca = ca.unshift(gcert) if not ca.first.equal?(gcert)
91
+ ca = ca.collect { |c|
92
+ Ccrypto::X509Cert.to_java_cert(c)
93
+ }
94
+
95
+ pass = block.call(:p12_pass) || block.call(:jks_pass)
96
+ raise KeypairEngineException, "Password is required" if is_empty?(pass)
97
+
98
+ name = block.call(:p12_name) || block.call(:jks_name)
99
+ name = "Ccrypto P12" if is_empty?(name)
100
+
101
+ keypair = block.call(:keypair)
102
+ raise KeypairEngineException, "Keypair is required" if is_empty?(keypair)
103
+
104
+ ks.setKeyEntry(name, keypair.private, pass.to_java.toCharArray, ca.to_java(java.security.cert.Certificate))
105
+
106
+ baos = java.io.ByteArrayOutputStream.new
107
+ ks.store(baos, pass.to_java.toCharArray)
108
+ res = baos.toByteArray
109
+
110
+ outForm = block.call(:out_format)
111
+ case outForm
112
+ when :b64
113
+ to_b64(res)
114
+ when :hex
115
+ to_hex(res)
116
+ else
117
+ res
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+ end