ccrypto-java 0.1.0

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