gcrypto_bc_cms 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d6bce44606b87f44bf8f5a369a1a68a1db2f0d4b
4
+ data.tar.gz: 04d34b485ed8bd970a4f995025139d57e39be52a
5
+ SHA512:
6
+ metadata.gz: 3e5b924be73243c34ff6c041635e991f2de35470c52ac8214fd7b19e72abf75e9a7755e3bc0f0cbe663d7c9846f66cb81b386774097d525b182c69a1d4305824
7
+ data.tar.gz: 5972177744a6c8c83103d40956615a8a110f254c399bac69e63fba48da29f7074b3b874e5b09f67b3050a2ab1e035812dfa19d90b58aaad9ddc73f2adb35be10
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /.DS_Store
10
+
11
+ /test/artifacts/
12
+ !/test/artifacts/.gitkeep
13
+ tags
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in gcrypto_bc_cms.gemspec
4
+ gemspec
5
+
6
+ gem 'pkernel', path: '../../pkernel/pkernel'
7
+ gem 'pkernel_jce', path: '../../pkernel/pkernel_jce'
8
+
9
+ gem 'gcrypto', path: '../gcrypto'
10
+ gem 'gcrypto_jce', path: '../gcrypto_jce'
@@ -0,0 +1,67 @@
1
+ PATH
2
+ remote: ../../pkernel/pkernel_jce
3
+ specs:
4
+ pkernel_jce (0.1.0)
5
+ activesupport
6
+ tlogger
7
+
8
+ PATH
9
+ remote: ../../pkernel/pkernel
10
+ specs:
11
+ pkernel (0.1.0)
12
+ tlogger
13
+
14
+ PATH
15
+ remote: ../gcrypto_jce
16
+ specs:
17
+ gcrypto_jce (0.1.0)
18
+ activesupport
19
+ pkernel
20
+ pkernel_jce
21
+ tlogger
22
+
23
+ PATH
24
+ remote: ../gcrypto
25
+ specs:
26
+ gcrypto (0.1.0)
27
+ pkernel
28
+ tlogger
29
+
30
+ PATH
31
+ remote: .
32
+ specs:
33
+ gcrypto_bc_cms (0.1.0)
34
+ tlogger
35
+
36
+ GEM
37
+ remote: https://rubygems.org/
38
+ specs:
39
+ activesupport (5.2.3)
40
+ concurrent-ruby (~> 1.0, >= 1.0.2)
41
+ i18n (>= 0.7, < 2)
42
+ minitest (~> 5.1)
43
+ tzinfo (~> 1.1)
44
+ concurrent-ruby (1.1.5)
45
+ i18n (1.6.0)
46
+ concurrent-ruby (~> 1.0)
47
+ minitest (5.11.3)
48
+ rake (10.5.0)
49
+ thread_safe (0.3.6-java)
50
+ tlogger (0.8.0)
51
+ tzinfo (1.2.5)
52
+ thread_safe (~> 0.1)
53
+
54
+ PLATFORMS
55
+ java
56
+
57
+ DEPENDENCIES
58
+ bundler (~> 2.0)
59
+ gcrypto!
60
+ gcrypto_bc_cms!
61
+ gcrypto_jce!
62
+ pkernel!
63
+ pkernel_jce!
64
+ rake (~> 10.0)
65
+
66
+ BUNDLED WITH
67
+ 2.0.2
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Chris Liaw
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,39 @@
1
+ # GcryptoBcCms
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/gcrypto_bc_cms`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'gcrypto_bc_cms'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install gcrypto_bc_cms
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/gcrypto_bc_cms.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "gcrypto_bc_cms"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,43 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "gcrypto_bc_cms/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "gcrypto_bc_cms"
8
+ spec.version = GcryptoBcCms::VERSION
9
+ spec.authors = ["Chris Liaw"]
10
+ spec.email = ["chrisliaw@antrapol.com"]
11
+
12
+ spec.summary = %q{}
13
+ spec.description = %q{}
14
+ spec.homepage = ""
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ #if spec.respond_to?(:metadata)
20
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
21
+
22
+ # spec.metadata["homepage_uri"] = spec.homepage
23
+ # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
24
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
25
+ #else
26
+ # raise "RubyGems 2.0 or newer is required to protect against " \
27
+ # "public gem pushes."
28
+ #end
29
+
30
+ # Specify which files should be added to the gem when it is released.
31
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
32
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
33
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
34
+ end
35
+ spec.bindir = "exe"
36
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
+ spec.require_paths = ["lib"]
38
+
39
+ spec.add_development_dependency "bundler", "~> 2.0"
40
+ spec.add_development_dependency "rake", "~> 10.0"
41
+
42
+ spec.add_dependency 'tlogger'
43
+ end
@@ -0,0 +1,15 @@
1
+
2
+ require 'gcrypto'
3
+ require "gcrypto_bc_cms/version"
4
+
5
+ require_relative 'gcrypto_bc_cms/keypair_crypto'
6
+
7
+ module GcryptoBcCms
8
+ class Error < StandardError; end
9
+ # Your code goes here...
10
+
11
+ class Gcrypto::KeyPairCms
12
+ extend GcryptoBcCms::KeyPairCrypto
13
+ end
14
+
15
+ end
@@ -0,0 +1,6 @@
1
+
2
+
3
+ module GcryptoBcCms
4
+ class Error < StandardError; end
5
+
6
+ end
@@ -0,0 +1,18 @@
1
+
2
+ require 'singleton'
3
+ require 'tlogger'
4
+
5
+ module GcryptoBcCms
6
+ class GConf
7
+ include Singleton
8
+ attr_reader :logger_params, :glog
9
+ def initialize
10
+ @logger_params = STDOUT
11
+ @glog = Tlogger.new(STDOUT)
12
+ @glog.tag = :gcrypto_bc_cms
13
+ @glog.show_source
14
+ end
15
+ end
16
+ end
17
+
18
+
@@ -0,0 +1,84 @@
1
+
2
+ module GcryptoBcCms
3
+ module IoUtils
4
+
5
+ def IoUtils.load_input(opts = { })
6
+ if opts.nil? or opts.empty?
7
+ raise GcryptoBcCms::Error, "No input given to load"
8
+ else
9
+ file = opts[:file]
10
+ bin = opts[:bin]
11
+
12
+ if not (file.nil? or file.empty?)
13
+ fis = java.io.FileInputStream.new(file)
14
+ fis
15
+ elsif not bin.nil?
16
+ begin
17
+ bais = java.io.ByteArrayInputStream.new(bin.to_java_bytes)
18
+ rescue NoMethodError
19
+ bais = java.io.ByteArrayInputStream.new(bin)
20
+ end
21
+ bais
22
+ else
23
+ raise GcryptoBcCms::Error, "Neither file nor bin given to load input"
24
+ end
25
+ end
26
+ end
27
+ #
28
+ # end load_input()
29
+ #
30
+
31
+ def IoUtils.read_chunk(is, opts = { },&block)
32
+
33
+ raise GcryptoBcCms::Error, "Cannot read chunk from nil input stream" if is.nil?
34
+ raise GcryptoBcCms::Error, "Block required for read_chunk" if not block
35
+
36
+ if not is.java_kind_of?(java.io.InputStream)
37
+ raise GcryptoBcCms::Error, "Cannot read from '#{is.class}' object"
38
+ end
39
+
40
+ bufLen = opts[:buffer_length] || 10240
41
+
42
+ b = Java::byte[bufLen].new
43
+ while((read = is.read(b,0,b.length)) != -1)
44
+ block.call(b,0,read)
45
+ end
46
+ end
47
+ #
48
+ # end read_chunk
49
+ #
50
+
51
+ def IoUtils.file_to_memory_byte_array(path)
52
+ if path.nil? or path.empty?
53
+ raise PkernelJce::Error, "Given path '#{path}' to load to memory is nil or empty"
54
+ else
55
+ f = java.io.File.new(path)
56
+ b = Java::byte[f.length].new
57
+ dis = java.io.DataInputStream.new(java.io.FileInputStream.new(f))
58
+ dis.readFully(b)
59
+ dis.close
60
+
61
+ b
62
+ end
63
+ end
64
+ # end file_to_memory_byte_array
65
+ #
66
+
67
+ def IoUtils.ensure_java_bytes(bin)
68
+ if not bin.java_kind_of?(Java::byte[])
69
+ bin.to_java_bytes
70
+ else
71
+ bin
72
+ end
73
+ end
74
+ # end ensure_java_bytes
75
+ #
76
+
77
+ end
78
+ # end IoUtils
79
+ #
80
+
81
+ end
82
+ # end GcryptoBcCms
83
+ #
84
+
@@ -0,0 +1,512 @@
1
+
2
+ require 'pkernel'
3
+ require 'pkernel_jce'
4
+
5
+ require 'gcrypto'
6
+ require 'gcrypto_jce'
7
+
8
+ require_relative 'error'
9
+ require_relative 'io_utils'
10
+ require_relative 'global'
11
+
12
+ module GcryptoBcCms
13
+ module KeyPairCrypto
14
+
15
+ #def sign(opts = { })
16
+ # raise GcryptoBcCms::Error, "Insufficient parameters for CMS signature generation" if opts.nil? or opts.empty?
17
+ #
18
+ # ids = opts[:identities]
19
+ # if ids.nil?
20
+ # raise GcryptoBcCms::Error, "Identity to sign the data is not available"
21
+ # end
22
+ # ids = [ids] if not ids.is_a?(Array)
23
+
24
+ # file = opts[:file]
25
+ # bin = opts[:bin]
26
+ # if not (file.nil? or file.empty?)
27
+ # msg = org.bouncycastle.cms.CMSProcessableFile.new(java.io.File.new(file))
28
+ # elsif not bin.nil?
29
+ # msg = org.bouncycastle.cms.CMSProcessableByteArray.new(IoUtils.ensure_java_bytes(bin))
30
+ # else
31
+ # raise GcryptoBcCms::Error, "No input is given for signing"
32
+ # end
33
+
34
+ # lst = java.util.ArrayList.new
35
+
36
+ # ids.each do |id|
37
+ # lst.add(id.certificate)
38
+ # end
39
+
40
+ # store = org.bouncycastle.cert.jcajce.JcaCertStore.new(lst)
41
+ # gen = org.bouncycastle.cms.CMSSignedDataGenerator.new
42
+ #
43
+ # signHash = opts[:signHash] || "SHA256"
44
+ # ids.each do |id|
45
+ # GcryptoBcCms::GConf.instance.glog.debug "Adding signer #{id.certificate.subjectDN}"
46
+ # prov = GcryptoJce::Provider.handle_options({ provider: id.provider })
47
+ # signer = org.bouncycastle.operator.jcajce.JcaContentSignerBuilder.new(Pkernel::KeyPair.derive_signing_algo(id.privKey, signHash)).setProvider(prov).build(id.privKey)
48
+ # infoGen = org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder.new(org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder.new.setProvider(prov).build()).build(signer, id.certificate)
49
+ # gen.addSignerInfoGenerator(infoGen)
50
+ # end
51
+
52
+ # gen.addCertificates(store)
53
+ #
54
+ # attachedSign = opts[:attachedSign]
55
+ # attachedSign = true if attachedSign.nil?
56
+ # gen.generate(msg, attachedSign)
57
+ #
58
+ #end
59
+ ##
60
+ ## end sign()
61
+ ##
62
+
63
+ def sign(opts = { })
64
+ raise GcryptoBcCms::Error, "Insufficient parameters for CMS signature generation" if opts.nil? or opts.empty?
65
+
66
+ ids = opts[:identities]
67
+ if ids.nil?
68
+ raise GcryptoBcCms::Error, "Identity to sign the data is not available"
69
+ end
70
+ ids = [ids] if not ids.is_a?(Array)
71
+
72
+ is = IoUtils.load_input(opts)
73
+
74
+ lst = java.util.ArrayList.new
75
+
76
+ ids.each do |id|
77
+ lst.add(id.certificate)
78
+ end
79
+
80
+ store = org.bouncycastle.cert.jcajce.JcaCertStore.new(lst)
81
+ gen = org.bouncycastle.cms.CMSSignedDataStreamGenerator.new
82
+
83
+ signHash = opts[:signHash] || "SHA256"
84
+ ids.each do |id|
85
+ GcryptoBcCms::GConf.instance.glog.debug "Adding signer #{id.certificate.subjectDN}"
86
+ prov = GcryptoJce::Provider.handle_options({ provider: id.provider })
87
+ signer = org.bouncycastle.operator.jcajce.JcaContentSignerBuilder.new(Pkernel::KeyPair.derive_signing_algo(id.privKey, signHash)).setProvider(prov).build(id.privKey)
88
+ infoGen = org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder.new(org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder.new.setProvider(prov).build()).build(signer, id.certificate)
89
+ gen.addSignerInfoGenerator(infoGen)
90
+ end
91
+
92
+ gen.addCertificates(store)
93
+ #gen.addCRLs(crlStore)
94
+
95
+ outFile = opts[:outFile]
96
+ if not (outFile.nil? or outFile.empty?)
97
+ os = java.io.FileOutputStream.new(outFile)
98
+ else
99
+ os = java.io.ByteArrayOutputStream.new
100
+ end
101
+
102
+ attachedSign = opts[:attachedSign]
103
+ attachedSign = true if attachedSign.nil?
104
+
105
+ sos = gen.open(os, attachedSign)
106
+
107
+ begin
108
+ bufConf = opts[:int_buf] || { }
109
+ total = 0
110
+ IoUtils.read_chunk(is, bufConf) do |buf, from, len|
111
+ sos.write(buf, from, len)
112
+ total += len
113
+ GcryptoJce::GConf.instance.glog.debug "Signed #{NumberHelper.number_to_human_size(total)}"
114
+ end
115
+ rescue Exception
116
+ ensure
117
+ begin
118
+ is.close
119
+ rescue Exception
120
+ end
121
+ begin
122
+ os.close
123
+ rescue Exception
124
+ end
125
+ begin
126
+ sos.close
127
+ rescue Exception
128
+ end
129
+ end
130
+
131
+ if outFile.nil? or outFile.empty?
132
+ os.toByteArray
133
+ end
134
+
135
+ end
136
+ #
137
+ # end sign()
138
+ #
139
+
140
+
141
+ def verify(opts = { })
142
+
143
+ if opts.nil? or opts.empty?
144
+ raise GcryptoBcCms::Error, "Insufficient parameters for CMS signature verification"
145
+ end
146
+
147
+ prov = GcryptoJce::Provider.handle_options(opts)
148
+
149
+ attachedSign = false
150
+ dataFile = opts[:file]
151
+ dataBin = opts[:bin]
152
+ if not (dataFile.nil? or dataFile.empty?)
153
+ data = org.bouncycastle.cms.CMSProcessableFile.new(java.io.File.new(dataFile))
154
+ elsif not dataBin.nil?
155
+ data = org.bouncycastle.cms.CMSProcessableByteArray.new(IoUtils.ensure_java_bytes(dataBin))
156
+ else
157
+ attachedSign = true
158
+ end
159
+
160
+ file = opts[:sign_file]
161
+ bin = opts[:sign_bin]
162
+ if not (file.nil? or file.empty?)
163
+ if attachedSign
164
+ signed = org.bouncycastle.cms.CMSSignedData.new(java.io.FileInputStream.new(file))
165
+ else
166
+ signed = org.bouncycastle.cms.CMSSignedData.new(data, java.io.FileInputStream.new(file))
167
+ end
168
+ elsif not bin.nil?
169
+ if attachedSign
170
+ signed = org.bouncycastle.cms.CMSSignedData.new(IoUtils.ensure_java_bytes(bin))
171
+ else
172
+ signed = org.bouncycastle.cms.CMSSignedData.new(data, IoUtils.ensure_java_bytes(bin))
173
+ end
174
+ else
175
+ raise GcryptoBcCms::Error, "Neither signature in file or memory buffer given for signatur verification"
176
+ end
177
+
178
+ outFile = opts[:out_file]
179
+ if not (outFile.nil? or outFile.empty?)
180
+ dataOs = java.io.FileOutputStream.new(outFile)
181
+ end
182
+
183
+ result = []
184
+ certs = signed.certificates
185
+ signerInfo = signed.getSignerInfos
186
+ signers = signerInfo.getSigners
187
+ signers.each do |signer|
188
+
189
+ certs.getMatches(signer.getSID).each do |c|
190
+ begin
191
+
192
+ GcryptoBcCms::GConf.instance.glog.debug "Verifying #{c.subject}..."
193
+ verifier = org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder.new.setProvider(prov).build(c)
194
+ if signer.verify(verifier)
195
+ GcryptoBcCms::GConf.instance.glog.debug "Signer #{c.subject} verified"
196
+ result << true
197
+ detail = { }
198
+ detail[:certificate] = c
199
+ if attachedSign
200
+ if dataOs.nil?
201
+ detail[:data] = signed.getSignedContent.getContent
202
+ else
203
+ begin
204
+ signed.getSignedContent.write(dataOs)
205
+ dataOs.flush
206
+ rescue Exception
207
+ ensure
208
+ begin
209
+ dataOs.close
210
+ rescue Exception
211
+ end
212
+ end
213
+
214
+ detail[:data_file] = outFile
215
+ end
216
+ # end if dataOs.nil?
217
+ end
218
+
219
+ result << detail
220
+
221
+ break
222
+ end
223
+
224
+ rescue Exception => ex
225
+ GcryptoBcCms::GConf.instance.glog.debug "#{c.subject} #{ex.message}"
226
+ end
227
+ end
228
+ # end certs.getMatches
229
+
230
+ break if not result.empty?
231
+ end
232
+ # end signers.each
233
+
234
+ result = [false] if result.empty?
235
+
236
+ result
237
+ end
238
+ #
239
+ # end verify()
240
+ #
241
+
242
+ def encrypt(opts = { })
243
+
244
+ is = IoUtils.load_input(opts)
245
+ rcpts = opts[:recipients]
246
+ if rcpts.nil? or rcpts.empty?
247
+ raise GcryptoBcCms::Error, "No recipients given to encrypt"
248
+ end
249
+
250
+ gen = org.bouncycastle.cms.CMSEnvelopedDataStreamGenerator.new
251
+ rcpts.each do |re|
252
+ gen.addRecipientInfoGenerator(KeyPairCrypto.to_enc_recipient_info(re))
253
+ end
254
+
255
+ outFile = opts[:outFile]
256
+ if outFile.nil? or outFile.empty?
257
+ out = java.io.ByteArrayOutputStream.new
258
+ else
259
+ out = java.io.FileOutputStream.new(outFile)
260
+ end
261
+
262
+ skCc = opts[:crypto_context]
263
+ if skCc.nil?
264
+ raise GcryptoBcCms::Error, "Crypto context is not available for CMS encrypt"
265
+ end
266
+
267
+ prov = GcryptoJce::Provider.handle_options(opts)
268
+ encOut = gen.open(out, org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder.new(KeyPairCrypto.to_bc_cms_algo(skCc)).setProvider(prov).build())
269
+
270
+ begin
271
+ bufConf = opts[:int_buf] || { }
272
+ total = 0
273
+ IoUtils.read_chunk(is, bufConf) do |buf, from, len|
274
+ encOut.write(buf, from, len)
275
+ total += len
276
+ GcryptoJce::GConf.instance.glog.debug "Processed #{NumberHelper.number_to_human_size(total)}"
277
+ end
278
+ rescue Exception
279
+ ensure
280
+ begin
281
+ is.close
282
+ rescue Exception
283
+ end
284
+ begin
285
+ out.close
286
+ rescue Exception
287
+ end
288
+ begin
289
+ encOut.close
290
+ rescue Exception
291
+ end
292
+ end
293
+
294
+ if outFile.nil? or outFile.empty?
295
+ out.toByteArray
296
+ end
297
+
298
+ end
299
+ #
300
+ # end encrypt()
301
+ #
302
+
303
+ def KeyPairCrypto.to_enc_recipient_info(obj, provider = GcryptoJce::Provider::DefProvider)
304
+ if obj.nil?
305
+ raise GcryptoBcCms::Error, "Given object to convert to recipient info is nil"
306
+ end
307
+
308
+ if Pkernel::Certificate.is_cert_object?(obj)
309
+ GcryptoBcCms::GConf.instance.glog.debug "Given recipient info is certificate"
310
+ cert = Pkernel::Certificate.ensure_java_cert(obj)
311
+ org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator.new(cert).setProvider(provider)
312
+ elsif GcryptoJce::SecretKey.is_secret_key?(obj)
313
+ GcryptoBcCms::GConf.instance.glog.debug "Given recipient info is secret key"
314
+ #org.bouncycastle.operator.jcajce.JceSymmetricKeyWrapper.new(obj).setProvider(provider)
315
+ org.bouncycastle.cms.jcajce.JceKEKRecipientInfoGenerator.new(SecureRandom.hex(8).to_java.getBytes, obj).setProvider(provider)
316
+ elsif obj.is_a?(Gcrypto::SecretKeyCryptoContext)
317
+ GcryptoBcCms::GConf.instance.glog.debug "Given recipient info is secret key crypto context"
318
+ prov = obj.key_provider
319
+ prov = provider if prov.nil?
320
+ #wrapper = org.bouncycastle.operator.jcajce.JceSymmetricKeyWrapper.new(obj.key).setProvider(prov)
321
+ org.bouncycastle.cms.jcajce.JceKEKRecipientInfoGenerator.new(obj.name.to_java.getBytes, obj.key).setProvider(prov)
322
+ elsif obj.is_a?(String)
323
+ GcryptoBcCms::GConf.instance.glog.debug "Given recipient info is string --> password recipient"
324
+ #algo = org.bouncycastle.cms.CMSAlgorithm::AES256_GCM
325
+ algo = org.bouncycastle.cms.CMSAlgorithm::AES256_CBC
326
+ salt = GcryptoJce::SecureRandomEngine.generate
327
+ iter = rand(1000...3000)
328
+ org.bouncycastle.cms.jcajce.JcePasswordRecipientInfoGenerator.new(algo, obj.to_java.toCharArray).setPasswordConversionScheme(org.bouncycastle.cms.PasswordRecipient::PKCS5_SCHEME2).setSaltAndIterationCount(salt,iter)
329
+ elsif obj.java_kind_of?(Java::byte[])
330
+ GcryptoBcCms::GConf.instance.glog.debug "Given recipient info is java byte array. Assume string --> password recipient"
331
+ #algo = org.bouncycastle.cms.CMSAlgorithm::AES256_GCM
332
+ algo = org.bouncycastle.cms.CMSAlgorithm::AES256_CBC
333
+ salt = GcryptoJce::SecureRandomEngine.generate
334
+ iter = rand(1000...3000)
335
+ org.bouncycastle.cms.jcajce.JcePasswordRecipientInfoGenerator.new(algo, String.from_java_bytes(obj).toCharArray).setPasswordConversionScheme(org.bouncycastle.cms.PasswordRecipient::PKCS5_SCHEME2).setSaltAndIterationCount(salt,iter)
336
+ elsif obj.java_kind_of?(Java::char[])
337
+ GcryptoBcCms::GConf.instance.glog.debug "Given recipient info is java char array. Assume string --> password recipient"
338
+ #algo = org.bouncycastle.cms.CMSAlgorithm::AES256_GCM
339
+ algo = org.bouncycastle.cms.CMSAlgorithm::AES256_CBC
340
+ salt = GcryptoJce::SecureRandomEngine.generate
341
+ iter = rand(1000...3000)
342
+ org.bouncycastle.cms.jcajce.JcePasswordRecipientInfoGenerator.new(algo, obj).setPasswordConversionScheme(org.bouncycastle.cms.PasswordRecipient::PKCS5_SCHEME2).setSaltAndIterationCount(salt,iter)
343
+ else
344
+ raise GcryptoBcCms::Error, "Unsupported object for encryption recipient info conversion '#{obj.class}'"
345
+ end
346
+ end
347
+ # end to_enc_recipient_info
348
+
349
+ def KeyPairCrypto.to_bc_cms_algo(algo)
350
+ case algo
351
+ when Gcrypto::SecretKeyCryptoContext
352
+ case algo.keyType
353
+ when :aes
354
+ case algo.keyLen
355
+ when 128, 192, 256
356
+ case algo.mode
357
+ when "CBC", "CCM", "GCM"
358
+ eval("org.bouncycastle.cms.CMSAlgorithm::AES#{algo.keyLen}_#{algo.mode}")
359
+ else
360
+ raise GcryptoBcCms::Error, "Unsupported mode '#{algo.mode}'"
361
+ end
362
+ # end case algo.mode
363
+ else
364
+ raise GcryptoBcCms::Error, "Unsupported key length '#{algo.keyLen}'"
365
+ end
366
+ # end case algo.keyLen
367
+ else
368
+ raise GcryptoBcCms::Error, "Unsupported key type '#{algo.keyType}'"
369
+ end
370
+ # end case algo.type
371
+ else
372
+ raise GcryptoBcCms::Error, "Unknown object to cms algo '#{algo.class}'"
373
+ end
374
+ # end case algo
375
+ end
376
+ # end to_be_cms_algo
377
+
378
+ def decrypt(opts = { })
379
+
380
+ id = opts[:identity]
381
+ sk = opts[:secret_key]
382
+ skcc = opts[:secret_key_cc]
383
+ pass = opts[:password]
384
+
385
+ if not id.nil?
386
+ cred = id.privKey
387
+ provider = id.provider
388
+ elsif not sk.nil?
389
+ cred = sk
390
+ provider = opts[:secret_key_provider]
391
+ elsif not skcc.nil?
392
+ cred = skcc
393
+ provider = skcc.key_provider
394
+ elsif not (pass.nil? or pass.empty?)
395
+ cred = pass
396
+ else
397
+ raise GcryptoBcCms::Error, "No decryption credential given to decrypt data"
398
+ end
399
+
400
+ is = IoUtils.load_input(opts)
401
+ envp = org.bouncycastle.cms.CMSEnvelopedData.new(is)
402
+
403
+ outFile = opts[:outFile]
404
+ if outFile.nil? or outFile.empty?
405
+ out = java.io.ByteArrayOutputStream.new
406
+ else
407
+ out = java.io.FileOutputStream.new(outFile)
408
+ end
409
+
410
+ kt = KeyPairCrypto.to_dec_recipient(cred, provider)
411
+
412
+ lastEx = nil
413
+ recipients = envp.getRecipientInfos.getRecipients
414
+ recipients.each do |r|
415
+
416
+ begin
417
+ encIs = r.getContentStream(kt).getContentStream
418
+ #rescue Java::OrgBouncycastleCms::CMSException => ex
419
+ rescue Exception => ex
420
+ lastEx = ex
421
+ #if ex.message =~ /Decryption error/
422
+ next
423
+ #end
424
+ end
425
+
426
+ begin
427
+ bufConf = opts[:int_buf] || { }
428
+ total = 0
429
+ IoUtils.read_chunk(encIs, bufConf) do |buf, from, len|
430
+ out.write(buf, from, len)
431
+ total += len
432
+ GcryptoJce::GConf.instance.glog.debug "Processed #{NumberHelper.number_to_human_size(total)}"
433
+ end
434
+ rescue Exception
435
+ ensure
436
+ begin
437
+ encIs.close
438
+ rescue Exception
439
+ end
440
+ begin
441
+ out.close
442
+ rescue Exception
443
+ end
444
+ end
445
+
446
+ lastEx = nil
447
+ break
448
+ end
449
+
450
+ if not lastEx.nil?
451
+ raise GcryptoBcCms::Error, lastEx
452
+ elsif outFile.nil? or outFile.empty?
453
+ out.toByteArray
454
+ end
455
+
456
+ end
457
+ #
458
+ # end decrypt()
459
+ #
460
+
461
+ def KeyPairCrypto.to_dec_recipient(obj, provider = GcryptoJce::Provider::DefProvider)
462
+ if obj.nil?
463
+ raise GcryptoBcCms::Error, "Given object to convert to recipient info is nil"
464
+ end
465
+
466
+ if Pkernel::KeyPair.is_private_key?(obj)
467
+ GcryptoBcCms::GConf.instance.glog.debug "Given decryption artifacts is private key"
468
+ org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient.new(obj).setProvider(provider)
469
+ elsif GcryptoJce::SecretKey.is_secret_key?(obj)
470
+ GcryptoBcCms::GConf.instance.glog.debug "Given decryption artifacts is secret key"
471
+ #w = org.bouncycastle.operator.jcajce.JceSymmetricKeyUnwrapper.new(obj).setProvider(provider)
472
+ if provider.nil?
473
+ org.bouncycastle.cms.jcajce.JceKEKEnvelopedRecipient.new(obj)
474
+ else
475
+ org.bouncycastle.cms.jcajce.JceKEKEnvelopedRecipient.new(obj).setProvider(provider)
476
+ end
477
+ elsif obj.is_a?(Gcrypto::SecretKeyCryptoContext)
478
+ prov = obj.key_provider
479
+ prov = provider if prov.nil?
480
+ if prov.nil?
481
+ GcryptoBcCms::GConf.instance.glog.debug "Given decryption artifacts is secret key crypto context."
482
+ org.bouncycastle.cms.jcajce.JceKEKEnvelopedRecipient.new(obj.key)
483
+ else
484
+ GcryptoBcCms::GConf.instance.glog.debug "Given decryption artifacts is secret key crypto context. '#{prov.nil? ? '' : "Using provider #{prov.name}" }'"
485
+ org.bouncycastle.cms.jcajce.JceKEKEnvelopedRecipient.new(obj.key).setProvider(prov)
486
+ end
487
+ #org.bouncycastle.operator.jcajce.JceSymmetricKeyUnwrapper.new(obj.key).setProvider(prov)
488
+ elsif obj.is_a?(String)
489
+ GcryptoBcCms::GConf.instance.glog.debug "Given decryption artifacts is string --> password recipient"
490
+ org.bouncycastle.cms.jcajce.JcePasswordEnvelopedRecipient.new(obj.to_java.toCharArray).setPasswordConversionScheme(org.bouncycastle.cms.PasswordRecipient::PKCS5_SCHEME2)
491
+ elsif obj.java_kind_of?(Java::byte[])
492
+ GcryptoBcCms::GConf.instance.glog.debug "Given decryption artifacts is java byte array. Assume string --> password recipient"
493
+ org.bouncycastle.cms.jcajce.JcePasswordEnvelopedRecipient.new(String.from_java_bytes(obj).to_java.toCharArray).setPasswordConversionScheme(org.bouncycastle.cms.PasswordRecipient::PKCS5_SCHEME2)
494
+ elsif obj.java_kind_of?(Java::char[])
495
+ GcryptoBcCms::GConf.instance.glog.debug "Given decryption artifacts is java char array. Assume string --> password recipient"
496
+ org.bouncycastle.cms.jcajce.JcePasswordEnvelopedRecipient.new(obj).setPasswordConversionScheme(org.bouncycastle.cms.PasswordRecipient::PKCS5_SCHEME2)
497
+ else
498
+ raise GcryptoBcCms::Error, "Unsupported object for decryption recipient object conversion '#{obj.class}'"
499
+ end
500
+ end
501
+ # end to_enc_recipient_info
502
+
503
+
504
+ end
505
+ # end module KeyPairCrypto
506
+
507
+
508
+ class KeyPairCryptoEngine
509
+ extend KeyPairCrypto
510
+ end
511
+
512
+ end
@@ -0,0 +1,3 @@
1
+ module GcryptoBcCms
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,52 @@
1
+
2
+
3
+ job :release do
4
+
5
+ include_job :prompt_version
6
+ #ver = prompt "Please provide version for this release:", required: true
7
+ #set :releasing_version, ver
8
+
9
+ include_job :check_in
10
+ include_job :build
11
+ end
12
+
13
+ job :prompt_version do
14
+ if get(:releasing_version) == nil
15
+ ver = prompt "Please provide version for this release:", required: true
16
+ set :releasing_version, ver
17
+ end
18
+ end
19
+
20
+ job :build do
21
+
22
+ dir File.dirname(__FILE__)
23
+
24
+ include_job :prompt_version
25
+
26
+ rubygem do
27
+ #publish build('alog.gemspec'), ignore_status: true #do |res|
28
+ build('gcrypto_bc_cms.gemspec') do |res|
29
+ publish(res, ignore_status: true)
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+
36
+ job :check_in do
37
+ dir File.dirname(__FILE__)
38
+ git do
39
+ commit
40
+ tag
41
+ push 'origin', 'master'
42
+ #push 'git','master'
43
+ end
44
+ end
45
+
46
+ job :reinstall do
47
+ rubygem do
48
+ uninstall 'gcrypto_bc_cms'
49
+ install 'gcrypto_bc_cms'
50
+ end
51
+ end
52
+
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gcrypto_bc_cms
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Chris Liaw
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-10-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ name: bundler
20
+ prerelease: false
21
+ type: :development
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '10.0'
33
+ name: rake
34
+ prerelease: false
35
+ type: :development
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ name: tlogger
48
+ prerelease: false
49
+ type: :runtime
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: ''
56
+ email:
57
+ - chrisliaw@antrapol.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - Gemfile.lock
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - bin/console
69
+ - bin/setup
70
+ - gcrypto_bc_cms.gemspec
71
+ - lib/gcrypto_bc_cms.rb
72
+ - lib/gcrypto_bc_cms/error.rb
73
+ - lib/gcrypto_bc_cms/global.rb
74
+ - lib/gcrypto_bc_cms/io_utils.rb
75
+ - lib/gcrypto_bc_cms/keypair_crypto.rb
76
+ - lib/gcrypto_bc_cms/version.rb
77
+ - release.job
78
+ homepage: ''
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 2.6.14.1
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: ''
102
+ test_files: []