gcrypto_bc_cms 0.1

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.
@@ -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: []