ccrypto 0.1.2 → 0.2.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.
@@ -0,0 +1,255 @@
1
+
2
+ require 'yaml'
3
+ require 'fileutils'
4
+
5
+ module Ccrypto
6
+ class InMemoryRecordError < StandardError; end
7
+
8
+ module InMemoryRecord
9
+ include TR::CondUtils
10
+
11
+ module ClassMethods
12
+
13
+ def record_storage_root=(val)
14
+ @store_root
15
+ FileUtils.mkdir_p(@store_root) if not File.exist?(@store_root)
16
+ end
17
+
18
+ def record_storage_root
19
+ if @store_root.nil?
20
+ @store_root = File.join(Dir.home,".ccrypto")
21
+ FileUtils.mkdir_p(@store_root) if not File.exist?(@store_root)
22
+ end
23
+ @store_root
24
+ end
25
+
26
+ def load_from_storage(record, &block)
27
+ recFile = File.join(record_storage_root, "#{record.gsub(" ","_")}.imr")
28
+ if File.exist?(recFile)
29
+ YAML.unsafe_load_file(recFile)
30
+ else
31
+ if block
32
+ block.call(:init_new_instance)
33
+ else
34
+ # try to do generic
35
+ eval("#{self.name}.new")
36
+ end
37
+ end
38
+ end
39
+ alias_method :load, :load_from_storage
40
+
41
+ end # ClassMethods
42
+ def self.included(klass)
43
+ klass.extend(ClassMethods)
44
+ @klass = klass
45
+ end
46
+
47
+ #
48
+ # Instance methods
49
+ #
50
+ def save_to_storage(record)
51
+ target = File.join(self.class.record_storage_root,"#{record}.imr")
52
+ File.open(target,"w") do |f|
53
+ f.write YAML.dump(self)
54
+ end
55
+ self
56
+ end
57
+ alias_method :save, :save_to_storage
58
+
59
+ def register(obj, opts = {})
60
+ logger.debug "Giving #{obj} to register"
61
+ if not obj.nil?
62
+ extrapolate(obj, opts)
63
+ logger.debug "Extrapolated object #{obj}"
64
+ records << obj
65
+ logger.debug "Object #{obj} added to records"
66
+ end
67
+ end
68
+
69
+ # finder only accept hash
70
+ def find(field)
71
+ res = []
72
+ case field
73
+ when Hash
74
+ loopRes = []
75
+ field.each do |k,v|
76
+ case v
77
+ when Array
78
+ # extra configration at value is array
79
+ # 1st parameter always the keyword to find
80
+ ss = v.first
81
+ fuzzy = v[1] || false
82
+ else
83
+ ss = v
84
+ fuzzy = false
85
+ end
86
+
87
+ if not searchRes[k.to_sym].nil?
88
+ if fuzzy
89
+ found = searchRes[k.to_sym].select { |sk,sv|
90
+ sk.to_s.downcase =~ /#{ss.downcase}/
91
+ }
92
+ loopRes = found.values
93
+ else
94
+ ss = ss.to_s.downcase
95
+ if searchRes[k.to_sym].keys.include?(ss)
96
+ loopRes = searchRes[k.to_sym][ss]
97
+ end
98
+ end
99
+ end
100
+
101
+ if is_empty?(res)
102
+ res = loopRes
103
+ else
104
+ res = res & loopRes
105
+ end
106
+ end
107
+ else
108
+ raise InMemoryRecordError, "Hash is expected for finder function"
109
+ end
110
+
111
+ # apparantly dup and clone has some different side effects
112
+ # dup will not copy the frozen flag but shall also ignore the dynamic method
113
+ # created using instance_eval
114
+ # clone shall retain the frozen flag but shall also carry over the instance_eval
115
+ # result.
116
+ # Hence let the application to decide to use dup or clone
117
+ res
118
+ #if field[:do_not_dup] == true
119
+ # res
120
+ #else
121
+ # # always return a copy instead of actual one
122
+ # # dup call here might not help if there are embedded
123
+ # # object in the class as the dup only does swallow
124
+ # # copy, not deep copy
125
+ # # Library user need to handle deep copy
126
+ # res.map { |r|
127
+ # if r.respond_to?(:ddup)
128
+ # r.ddup
129
+ # else
130
+ # r.clone
131
+ # end
132
+ # }
133
+ #end
134
+
135
+ end # find() operation
136
+
137
+ def each(&block)
138
+ raise InMemoryRecordError, "each function requires a block" if not block
139
+ records.each(&block)
140
+ #records.map {|r|
141
+ # if r.respond_to?(:ddup)
142
+ # r.ddup
143
+ # else
144
+ # r.clone
145
+ # end
146
+ #}.each(&block)
147
+ end
148
+
149
+ def collect(&block)
150
+ records.collect(&block)
151
+ end
152
+
153
+ def select(&block)
154
+ records.select(&block)
155
+ #records.map { |r|
156
+ # if r.respond_to?(:ddup)
157
+ # r.ddup
158
+ # else
159
+ # r.clone
160
+ # end
161
+ #}.select(&block)
162
+ end
163
+
164
+ def empty?
165
+ records.empty?
166
+ end
167
+
168
+ def to_a
169
+ records #.freeze
170
+ #records.map { |c|
171
+ # if c.respond_to?(:ddup)
172
+ # c.ddup
173
+ # else
174
+ # c.clone
175
+ # end
176
+ #}.freeze
177
+ end
178
+
179
+ private
180
+ def records
181
+ if @records.nil?
182
+ @records = []
183
+ end
184
+ @records
185
+ end
186
+
187
+ def define_search_key(*args)
188
+ args.map { |s|
189
+ raise InMemoryRecordError, "Only support Symbol/String as search key" if not [String, Symbol].include?(s.class)
190
+ }
191
+ searchKeys.concat(args)
192
+ end
193
+
194
+ def extrapolate(a, opts = {})
195
+ if not_empty?(opts) and not_empty?(opts[:tag_under])
196
+ tag = opts[:tag_under]
197
+ searchRes[tag] = {} if searchRes[tag].nil?
198
+
199
+ val = opts[:tag_value]
200
+ val = val.to_s.downcase
201
+
202
+ if not_empty?(val)
203
+ searchRes[tag][val] = [] if searchRes[tag][val].nil?
204
+ searchRes[tag][val] << a
205
+ logger.debug "Registering #{tag}/#{val}"
206
+
207
+ else
208
+ raise InMemoryRecordError, ":tag_under requires :tag_value to operate"
209
+ end
210
+ end # additional tagging
211
+
212
+ searchKeys.each do |ss|
213
+ case ss
214
+ when Symbol, String
215
+ val = a.send(ss)
216
+ #logger.debug "Extrapolating #{ss} got : #{val}"
217
+ if not_empty?(val)
218
+ val = val.to_s.downcase
219
+ # search field has value
220
+ searchRes[ss.to_sym] = {} if searchRes[ss.to_sym].nil?
221
+ searchRes[ss.to_sym][val] = [] if searchRes[ss.to_sym][val].nil?
222
+ searchRes[ss.to_sym][val] << a
223
+ logger.debug "Registering #{ss.to_sym}/#{val}"
224
+ end
225
+ end
226
+ end
227
+ end
228
+
229
+ def searchKeys
230
+ if @searchKeys.nil?
231
+ @searchKeys = []
232
+ end
233
+ @searchKeys
234
+ end
235
+
236
+ def searchRes
237
+ if @searchRes.nil?
238
+ @searchRes = {}
239
+ end
240
+ @searchRes
241
+ end
242
+
243
+ def hash_tree
244
+ Hash.new do |hash, key|
245
+ hash[key] = hash_tree
246
+ end
247
+ end
248
+
249
+ def logger
250
+ Ccrypto.logger(:inMemRec)
251
+ end
252
+
253
+
254
+ end
255
+ end
@@ -2,12 +2,31 @@
2
2
 
3
3
  module Ccrypto
4
4
  module KeyBundle
5
- attr_accessor :nativeKeypair
5
+ attr_reader :nativeKeypair
6
6
 
7
7
  def KeyBundle.from_storage(*args, &block)
8
8
  Provider.instance.provider.keybundle_from_storage(*args, &block)
9
9
  end
10
10
 
11
+ def native
12
+ @nativeKeypair
13
+ end
14
+ alias_method :keypair, :native
15
+
16
+ private
17
+ def method_missing(mtd, *args, &block)
18
+ if not @nativeKeypair.nil?
19
+ logger.debug "Sending to method #{mtd} of object '#{@nativeKeypair}' at KeyBundle level"
20
+ @nativeKeypair.send(mtd, *args, &block)
21
+ else
22
+ super
23
+ end
24
+ end
25
+
26
+ def logger
27
+ Ccrypto.logger(:keybundle)
28
+ end
29
+
11
30
  end
12
31
 
13
32
  module ECCKeyBundle
@@ -0,0 +1,25 @@
1
+
2
+
3
+ module Ccrypto
4
+ module Keystore
5
+
6
+ class KeystoreException < StandardError; end
7
+
8
+ def Keystore.load_keystore(*args, &block)
9
+ Provider.instance.provider.load_keystore(*args, &block)
10
+ end
11
+
12
+ def Keystore.load_keystore_file(*args, &block)
13
+ Provider.instance.provider.load_keystore_file(*args, &block)
14
+ end
15
+
16
+ def Keystore.convert_keystore(*args, &block)
17
+ Provider.instance.provider.convert_keystore(*args, &block)
18
+ end
19
+
20
+ def Keystore.convert_keystore_file(*args, &block)
21
+ Provider.instance.provider.convert_keystore_file(*args, &block)
22
+ end
23
+
24
+ end
25
+ end
@@ -23,10 +23,18 @@ module Ccrypto
23
23
  end
24
24
  end
25
25
 
26
+ def native
27
+ @native_privKey
28
+ end
29
+
26
30
  end # PrivateKey
27
31
 
28
32
  class ECCPrivateKey < PrivateKey; end
29
33
  class RSAPrivateKey < PrivateKey; end
30
34
  class ED25519PrivateKey < PrivateKey; end
31
35
  class X25519PrivateKey < PrivateKey; end
36
+
37
+ class CrystalDilithiumPrivateKey < PrivateKey; end
38
+ class CrystalKyberPrivateKey < PrivateKey; end
39
+
32
40
  end
@@ -7,10 +7,20 @@ module Ccrypto
7
7
  @native_pubKey = pubkey
8
8
  end
9
9
 
10
+ def native
11
+ @native_pubKey
12
+ end
13
+
14
+ private
15
+ def logger
16
+ Ccrypto.logger(:pubkey)
17
+ end
18
+
10
19
  def method_missing(mtd, *args, &block)
11
20
  if @native_pubKey.nil?
12
21
  super
13
22
  else
23
+ logger.debug "Sending to native pubKey '#{@native_pubKey}' of method '#{mtd}'"
14
24
  @native_pubKey.send(mtd, *args, &block)
15
25
  end
16
26
  end
@@ -29,4 +39,7 @@ module Ccrypto
29
39
  class RSAPublicKey < PublicKey; end
30
40
  class ED25519PublicKey < PublicKey; end
31
41
  class X25519PublicKey < PublicKey; end
42
+
43
+ class CrystalDilithiumPublicKey < PublicKey; end
44
+ class CrystalKyberPublicKey < PublicKey; end
32
45
  end
@@ -2,12 +2,17 @@
2
2
 
3
3
  module Ccrypto
4
4
  class SecretKey
5
- attr_accessor :algo
6
- attr_accessor :key
5
+ attr_reader :algo, :keysize
7
6
 
8
- def initialize(algo, key)
7
+ attr_reader :native_key
8
+
9
+ attr_accessor :provider_config
10
+
11
+ def initialize(algo, keysize, key)
9
12
  @algo = algo
10
- @key = key
13
+ @keysize = keysize
14
+ @native_key = key
11
15
  end
16
+
12
17
  end
13
18
  end
@@ -1,5 +1,8 @@
1
1
 
2
- require 'singleton'
2
+ require 'yaml'
3
+ require 'fileutils'
4
+
5
+ require_relative 'in_memory_record'
3
6
 
4
7
  module Ccrypto
5
8
 
@@ -7,120 +10,10 @@ module Ccrypto
7
10
 
8
11
  class SupportedCipherList
9
12
  include TR::CondUtils
10
- include Singleton
11
-
12
- include TeLogger::TeLogHelper
13
- teLogger_tag :supCipherList
13
+ include InMemoryRecord
14
14
 
15
15
  def initialize
16
- @algos = {}
17
- @keysizes = {}
18
- @modes = {}
19
-
20
- @algoKeysize = {}
21
- @algoKeysizeMode = {}
22
- @keysizeMode = {}
23
- @algoMode = {}
24
- @items = []
25
- end
26
-
27
- def register(cc)
28
- raise SupportedCipherListError, "Ccrypto::CipherConfig required. Got '#{cc.class}'" if not cc.is_a?(Ccrypto::CipherConfig)
29
-
30
- @items << cc
31
- algo = cc.algo.to_sym
32
- @algos[algo] = [] if @algos[algo].nil?
33
- @algos[algo] << cc
34
-
35
- keysize = cc.keysize.to_s
36
- @keysizes[keysize] = [] if @keysizes[keysize].nil?
37
- @keysizes[keysize] << cc
38
-
39
- mode = cc.mode.nil? ? "" : cc.mode.to_s
40
- if not_empty?(mode)
41
- @modes[mode.to_s] = [] if @modes[mode.to_s].nil?
42
- @modes[mode.to_s] << cc
43
- end
44
-
45
- @algoKeysize[algo] = { } if @algoKeysize[algo].nil?
46
- @algoKeysize[algo][keysize] = [] if @algoKeysize[algo][keysize].nil?
47
- @algoKeysize[algo][keysize] << cc
48
-
49
- if not_empty?(mode)
50
- @algoMode[algo] = {} if @algoMode[algo].nil?
51
- @algoMode[algo][mode] = [] if @algoMode[algo][mode].nil?
52
- @algoMode[algo][mode] << cc
53
-
54
- @keysizeMode[keysize] = {} if @keysizeMode[keysize].nil?
55
- @keysizeMode[keysize][mode] = [] if @keysizeMode[keysize][mode].nil?
56
- @keysizeMode[keysize][mode] << cc
57
-
58
- @algoKeysizeMode[algo] = {} if @algoKeysizeMode[algo].nil?
59
- @algoKeysizeMode[algo][keysize] = {} if @algoKeysizeMode[algo][keysize].nil?
60
- @algoKeysizeMode[algo][keysize][mode] = [] if @algoKeysizeMode[algo][keysize][mode].nil?
61
- @algoKeysizeMode[algo][keysize][mode] << cc
62
- end
63
-
64
- end
65
-
66
- def items
67
- @items
68
- end
69
-
70
- def each(&block)
71
- @items.each(&block)
72
- end
73
-
74
- def algo_count
75
- @algos.length
76
- end
77
- def find_algo(algo)
78
- @algos[algo.to_sym] || []
79
- end
80
- def algos
81
- @algos.keys
82
- end
83
-
84
- def keysizes_count
85
- @keysizes.length
86
- end
87
- def keysizes
88
- @keysizes.keys
89
- end
90
- def find_keysize(keysize)
91
- @keysizes[keysize.to_s]
92
- end
93
-
94
- def mode_count
95
- @modes.length
96
- end
97
- def find_mode(mode)
98
- @modes[mode.to_s]
99
- end
100
- def modes
101
- @modes.keys
102
- end
103
-
104
- def find_algo_keysize(algo, keysize)
105
- res = @algoKeysize[algo.to_sym] || { }
106
- res[keysize.to_s] || []
107
- end
108
-
109
- def find_algo_mode(algo, mode)
110
- res = @algoMode[algo.to_sym] || {}
111
- res[mode.to_s] || []
112
- end
113
-
114
- def find_algo_keysize_mode(algo, keysize, mode)
115
- res = @algoKeysizeMode[algo.to_sym] || {}
116
- res = res[keysize.to_s] || {}
117
- res[mode.to_s] || []
118
- end
119
-
120
- def find_keysize_modes(keysize, mode)
121
-
122
- res = @keysizeMode[keysize.to_s] || {}
123
- res[mode.to_s] || []
16
+ define_search_key(:algo, :keysize, :mode, :padding, :ivLength)
124
17
  end
125
18
 
126
19
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ccrypto
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -8,5 +8,10 @@ module Ccrypto
8
8
  @nativeX509 = x509
9
9
  end
10
10
 
11
+ def X509Cert.load_x509(*args, &block)
12
+ Provider.instance.provider.load_x509(*args, &block)
13
+ end
14
+
15
+
11
16
  end
12
17
  end
@@ -4,6 +4,8 @@ module Ccrypto
4
4
  class X509CSR
5
5
  attr_accessor :nativeCSR
6
6
 
7
+ class X509CSRSignatureInvalid < StandardError; end
8
+
7
9
  def initialize(csr)
8
10
  @nativeCSR = csr
9
11
  end
data/lib/ccrypto.rb CHANGED
@@ -26,7 +26,16 @@ require_relative 'ccrypto/secret_key'
26
26
  require_relative 'ccrypto/x509_cert'
27
27
  require_relative 'ccrypto/x509_csr'
28
28
 
29
+ require_relative 'ccrypto/digest_matcher'
30
+ require_relative 'ccrypto/in_memory_record'
31
+
32
+ require_relative 'ccrypto/keystore'
33
+
34
+ require_relative 'ccrypto/capability'
35
+
29
36
  module Ccrypto
37
+ include TR::CondUtils
38
+
30
39
  class Error < StandardError; end
31
40
  class CcryptoProviderException < StandardError; end
32
41
 
@@ -56,4 +65,39 @@ module Ccrypto
56
65
 
57
66
  class KeyBundleStorageException < StandardError; end
58
67
  # Your code goes here...
68
+
69
+ Root_OID = ["2","0","18"]
70
+
71
+ def self.logger(tag = nil, &block)
72
+ if @_logger.nil?
73
+ @_logger = TeLogger::Tlogger.new
74
+ end
75
+
76
+ if block
77
+ if not_empty?(tag)
78
+ @_logger.with_tag(tag, &block)
79
+ else
80
+ @_logger.with_tag(@_logger.tag, &block)
81
+ end
82
+ else
83
+ if is_empty?(tag)
84
+ @_logger.tag = :CryptoJava
85
+ @_logger
86
+ else
87
+ # no block but tag is given? hmm
88
+ @_logger.tag = tag
89
+ @_logger
90
+ end
91
+ end
92
+
93
+ end
94
+
95
+ def self.if_detail_debug(msg)
96
+ logger.tdebug(:ccrypto_detail_debug, msg) if is_detail_debug_on?
97
+ end
98
+
99
+ def self.is_detail_debug_on?
100
+ ENV['CCRYPTO_DEBUG'] == "true"
101
+ end
102
+
59
103
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ccrypto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-30 00:00:00.000000000 Z
11
+ date: 2023-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: teLogger
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: devops_assist
56
+ name: release-gem
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -76,6 +76,7 @@ extra_rdoc_files: []
76
76
  files:
77
77
  - ".release_history.yml"
78
78
  - ".rspec"
79
+ - ".rubocop.yml"
79
80
  - Gemfile
80
81
  - Gemfile.lock
81
82
  - README.md
@@ -87,6 +88,7 @@ files:
87
88
  - lib/ccrypto/algo_factory.rb
88
89
  - lib/ccrypto/asn1.rb
89
90
  - lib/ccrypto/asn1_object.rb
91
+ - lib/ccrypto/capability.rb
90
92
  - lib/ccrypto/configs/algo_config.rb
91
93
  - lib/ccrypto/configs/cipher_config.rb
92
94
  - lib/ccrypto/configs/compress_config.rb
@@ -100,7 +102,10 @@ files:
100
102
  - lib/ccrypto/configs/secure_random_config.rb
101
103
  - lib/ccrypto/configs/x509_cert_profile.rb
102
104
  - lib/ccrypto/configs/x509_csr_profile.rb
105
+ - lib/ccrypto/digest_matcher.rb
106
+ - lib/ccrypto/in_memory_record.rb
103
107
  - lib/ccrypto/key_bundle.rb
108
+ - lib/ccrypto/keystore.rb
104
109
  - lib/ccrypto/private_key.rb
105
110
  - lib/ccrypto/provider.rb
106
111
  - lib/ccrypto/public_key.rb
@@ -113,7 +118,7 @@ files:
113
118
  homepage: https://github.com/cameronian/ccrypto
114
119
  licenses: []
115
120
  metadata: {}
116
- post_install_message:
121
+ post_install_message:
117
122
  rdoc_options: []
118
123
  require_paths:
119
124
  - lib
@@ -128,8 +133,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
133
  - !ruby/object:Gem::Version
129
134
  version: '0'
130
135
  requirements: []
131
- rubygems_version: 3.4.6
132
- signing_key:
136
+ rubygems_version: 3.5.1
137
+ signing_key:
133
138
  specification_version: 4
134
139
  summary: Crypto API normalization for Ruby and Java
135
140
  test_files: []