ccrypto 0.1.0 → 0.1.3
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.
- checksums.yaml +4 -4
- data/.release_history.yml +8 -0
- data/Gemfile.lock +59 -18
- data/ccrypto.gemspec +2 -2
- data/lib/ccrypto/configs/cipher_config.rb +93 -38
- data/lib/ccrypto/configs/kdf_config.rb +44 -3
- data/lib/ccrypto/configs/key_config.rb +4 -0
- data/lib/ccrypto/configs/keypair_config.rb +82 -5
- data/lib/ccrypto/configs/x509_cert_profile.rb +90 -3
- data/lib/ccrypto/configs/x509_csr_profile.rb +147 -0
- data/lib/ccrypto/key_bundle.rb +13 -0
- data/lib/ccrypto/private_key.rb +2 -0
- data/lib/ccrypto/public_key.rb +2 -0
- data/lib/ccrypto/supported_cipher_list.rb +141 -0
- data/lib/ccrypto/version.rb +1 -1
- data/lib/ccrypto/x509_csr.rb +11 -0
- data/lib/ccrypto.rb +10 -1
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d78804b935e3d34f37fb6a0923bf58fd0c7eb8d23686b7da39233c7faee7fcc6
|
4
|
+
data.tar.gz: a9b72eb6dd16aceb1d0ae3dbd7171df9ae0b5113a3e45df5340f9e880331686e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17e938a40eb693df83d24341c1400d59640d65e49e53535f838dd918abf5016f541b80897fcb04d3ed4b45a14bcf035cfc7405ce8dbd3c1783c4ef1472874393
|
7
|
+
data.tar.gz: f4efc3711e6886ff8ad32e846cf2db74478197e4643a1a5065e938f7f40acbe4515d46cd9d5d9473ad49ae2ef55a5b2a4a1bc2920f1532546ea9ec4c6305747a
|
data/Gemfile.lock
CHANGED
@@ -1,40 +1,81 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ccrypto (0.1.
|
4
|
+
ccrypto (0.1.3)
|
5
|
+
activesupport
|
5
6
|
teLogger
|
6
7
|
toolrack
|
7
8
|
|
8
9
|
GEM
|
9
10
|
remote: https://rubygems.org/
|
10
11
|
specs:
|
11
|
-
|
12
|
+
activesupport (7.0.4.3)
|
13
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
|
+
i18n (>= 1.6, < 2)
|
15
|
+
minitest (>= 5.1)
|
16
|
+
tzinfo (~> 2.0)
|
17
|
+
concurrent-ruby (1.2.2)
|
18
|
+
devops_assist (0.3.11)
|
19
|
+
git_cli
|
20
|
+
git_cli_prompt (~> 0.3.3)
|
21
|
+
gvcs
|
22
|
+
teLogger
|
23
|
+
toolrack
|
24
|
+
tty-prompt
|
12
25
|
diff-lcs (1.5.0)
|
26
|
+
git_cli (0.11.2)
|
27
|
+
gvcs
|
28
|
+
ptools (~> 1.4.0)
|
29
|
+
teLogger
|
30
|
+
toolrack
|
31
|
+
git_cli_prompt (0.3.4)
|
32
|
+
teLogger
|
33
|
+
toolrack
|
34
|
+
tty-prompt
|
35
|
+
gvcs (0.1.1)
|
36
|
+
i18n (1.12.0)
|
37
|
+
concurrent-ruby (~> 1.0)
|
38
|
+
minitest (5.18.0)
|
39
|
+
pastel (0.8.0)
|
40
|
+
tty-color (~> 0.5)
|
41
|
+
ptools (1.4.3)
|
13
42
|
rake (13.0.6)
|
14
|
-
rspec (3.
|
15
|
-
rspec-core (~> 3.
|
16
|
-
rspec-expectations (~> 3.
|
17
|
-
rspec-mocks (~> 3.
|
18
|
-
rspec-core (3.
|
19
|
-
rspec-support (~> 3.
|
20
|
-
rspec-expectations (3.
|
43
|
+
rspec (3.12.0)
|
44
|
+
rspec-core (~> 3.12.0)
|
45
|
+
rspec-expectations (~> 3.12.0)
|
46
|
+
rspec-mocks (~> 3.12.0)
|
47
|
+
rspec-core (3.12.1)
|
48
|
+
rspec-support (~> 3.12.0)
|
49
|
+
rspec-expectations (3.12.2)
|
21
50
|
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
-
rspec-support (~> 3.
|
23
|
-
rspec-mocks (3.
|
51
|
+
rspec-support (~> 3.12.0)
|
52
|
+
rspec-mocks (3.12.5)
|
24
53
|
diff-lcs (>= 1.2.0, < 2.0)
|
25
|
-
rspec-support (~> 3.
|
26
|
-
rspec-support (3.
|
27
|
-
teLogger (0.
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
54
|
+
rspec-support (~> 3.12.0)
|
55
|
+
rspec-support (3.12.0)
|
56
|
+
teLogger (0.2.2)
|
57
|
+
toolrack (0.21.0)
|
58
|
+
tty-color (0.6.0)
|
59
|
+
tty-cursor (0.7.1)
|
60
|
+
tty-prompt (0.23.1)
|
61
|
+
pastel (~> 0.8)
|
62
|
+
tty-reader (~> 0.8)
|
63
|
+
tty-reader (0.9.0)
|
64
|
+
tty-cursor (~> 0.7)
|
65
|
+
tty-screen (~> 0.8)
|
66
|
+
wisper (~> 2.0)
|
67
|
+
tty-screen (0.8.1)
|
68
|
+
tzinfo (2.0.6)
|
69
|
+
concurrent-ruby (~> 1.0)
|
70
|
+
wisper (2.0.1)
|
32
71
|
|
33
72
|
PLATFORMS
|
73
|
+
ruby
|
34
74
|
x86_64-linux
|
35
75
|
|
36
76
|
DEPENDENCIES
|
37
77
|
ccrypto!
|
78
|
+
devops_assist
|
38
79
|
rake (~> 13.0)
|
39
80
|
rspec (~> 3.0)
|
40
81
|
|
data/ccrypto.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["Ian"]
|
9
9
|
spec.email = ["cameronian0@protonmail.com"]
|
10
10
|
|
11
|
-
spec.summary = ""
|
12
|
-
spec.description = ""
|
11
|
+
spec.summary = "Crypto API normalization for Ruby and Java"
|
12
|
+
spec.description = "Attempt to have a common crypto for Ruby and Java to take the selection decision out from the application development until further date"
|
13
13
|
spec.homepage = "https://github.com/cameronian/ccrypto"
|
14
14
|
spec.required_ruby_version = ">= 2.4.0"
|
15
15
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Ccrypto
|
4
4
|
|
5
|
-
module
|
5
|
+
module CipherAuthMode
|
6
6
|
attr_accessor :auth_data, :auth_tag
|
7
7
|
end
|
8
8
|
|
@@ -15,23 +15,42 @@ module Ccrypto
|
|
15
15
|
attr_accessor :iv, :ivLength
|
16
16
|
attr_accessor :cipherOps
|
17
17
|
|
18
|
+
# required by certain mode such as CCM
|
19
|
+
attr_accessor :plaintext_length, :ciphertext_length, :fixed_auth_tag_length
|
20
|
+
|
21
|
+
# Use cases :
|
22
|
+
# openssl aes-128-xts only accepts input min 16 bytes
|
23
|
+
# other no padding mode aes128-wrap only works on block of 8 bytes
|
24
|
+
attr_reader :min_input_length, :mandatory_block_size
|
25
|
+
|
26
|
+
# provider specific
|
27
|
+
attr_accessor :native_config
|
28
|
+
|
18
29
|
def initialize(algo, opts = { }, &block)
|
19
30
|
@algo = algo
|
20
31
|
|
21
32
|
@logger = Tlogger.new
|
22
33
|
@logger.tag = :cipher_conf
|
34
|
+
|
35
|
+
@authMode = false
|
36
|
+
@plaintext_length = 0
|
37
|
+
@ciphertext_length = 0
|
38
|
+
@min_input_length = -1
|
39
|
+
@mandatory_Block_size = -1
|
40
|
+
@fixed_iv_length = -1
|
23
41
|
|
24
42
|
if not_empty?(opts) and opts.is_a?(Hash)
|
25
43
|
@mode = opts[:mode]
|
26
44
|
|
27
|
-
|
28
|
-
|
29
|
-
|
45
|
+
@authMode = opts[:authMode] || false
|
46
|
+
#if is_mode?(:gcm)
|
47
|
+
if @authMode
|
48
|
+
self.extend CipherAuthMode
|
49
|
+
@logger.debug "Extending auth mode"
|
30
50
|
|
31
51
|
@auth_data = opts[:auth_data]
|
32
52
|
@auth_tag = opts[:auth_tag]
|
33
53
|
|
34
|
-
#p "auth data : #{@auth_data}"
|
35
54
|
end
|
36
55
|
|
37
56
|
@iv = opts[:iv]
|
@@ -43,29 +62,43 @@ module Ccrypto
|
|
43
62
|
@padding = opts[:padding]
|
44
63
|
|
45
64
|
@cipherOps = opts[:cipherOps]
|
65
|
+
|
66
|
+
@min_input_length = opts[:min_input_length] || -1
|
67
|
+
|
68
|
+
@mandatory_block_size = opts[:mandatory_block_size] || -1
|
69
|
+
|
70
|
+
@fixed_auth_tag_length = opts[:fixed_auth_tag_length] || -1
|
71
|
+
|
46
72
|
end
|
47
73
|
|
48
|
-
if block
|
49
|
-
|
74
|
+
#if block
|
75
|
+
# @mode = block.call(:mode)
|
50
76
|
|
51
|
-
|
52
|
-
|
53
|
-
|
77
|
+
# #if is_mode?(:gcm)
|
78
|
+
# if @authMode
|
79
|
+
# self.extend CipherAuthMode
|
80
|
+
# @logger.debug "Extending auth mode"
|
54
81
|
|
55
|
-
|
56
|
-
|
57
|
-
|
82
|
+
# @auth_data = block.call(:auth_data)
|
83
|
+
# @auth_tag = block.call(:auth_tag)
|
84
|
+
# end
|
58
85
|
|
59
|
-
|
60
|
-
|
86
|
+
# @iv = block.call(:iv)
|
87
|
+
# @ivLength = block.call(:ivLength) || 16 if @iv.nil?
|
61
88
|
|
62
|
-
|
63
|
-
|
89
|
+
# @key = block.call(:key)
|
90
|
+
# @keysize = block.call(:keysize) if @key.nil?
|
64
91
|
|
65
|
-
|
92
|
+
# @padding = block.call(:padding)
|
66
93
|
|
67
|
-
|
68
|
-
|
94
|
+
# @cipherOps = block.call(:cipherOps)
|
95
|
+
|
96
|
+
# @plaintext_length = 0
|
97
|
+
# @ciphertext_length = 0
|
98
|
+
|
99
|
+
# @min_input_length = opts[:min_input_length] || -1
|
100
|
+
|
101
|
+
#end
|
69
102
|
|
70
103
|
end
|
71
104
|
|
@@ -77,6 +110,18 @@ module Ccrypto
|
|
77
110
|
not_empty?(@key)
|
78
111
|
end
|
79
112
|
|
113
|
+
def has_min_input_length?
|
114
|
+
not_empty?(@min_input_length) and @min_input_length.to_i > -1
|
115
|
+
end
|
116
|
+
|
117
|
+
def has_fixed_auth_tag_length?
|
118
|
+
not_empty?(@fixed_auth_tag_length) and @fixed_auth_tag_length.to_i > -1
|
119
|
+
end
|
120
|
+
|
121
|
+
def is_auth_mode_cipher?
|
122
|
+
@authMode == true
|
123
|
+
end
|
124
|
+
|
80
125
|
def is_algo?(algo)
|
81
126
|
if @algo.nil? or is_empty?(@algo)
|
82
127
|
false
|
@@ -89,10 +134,18 @@ module Ccrypto
|
|
89
134
|
if @mode.nil? or is_empty?(@mode)
|
90
135
|
false
|
91
136
|
else
|
92
|
-
(@mode.to_s.downcase =~ /#{mode.to_s}/) != nil
|
137
|
+
(@mode.to_s.downcase =~ /#{mode.to_s.downcase}/) != nil
|
93
138
|
end
|
94
139
|
end
|
95
140
|
|
141
|
+
def needs_plaintext_length?
|
142
|
+
is_mode?(:ccm)
|
143
|
+
end
|
144
|
+
|
145
|
+
def needs_ciphertext_length?
|
146
|
+
is_mode?(:ccm)
|
147
|
+
end
|
148
|
+
|
96
149
|
def encrypt_cipher_mode
|
97
150
|
@cipherOps = :encrypt
|
98
151
|
end
|
@@ -118,7 +171,9 @@ module Ccrypto
|
|
118
171
|
end
|
119
172
|
|
120
173
|
def to_s
|
121
|
-
|
174
|
+
res = [@algo, @keysize, @mode, @padding].reject { |v| is_empty?(v) }.join("-")
|
175
|
+
"#{res} (#{@authMode})"
|
176
|
+
#"#{@algo}-#{@keysize}-#{@mode}-#{@padding}"
|
122
177
|
end
|
123
178
|
|
124
179
|
def logger
|
@@ -130,21 +185,21 @@ module Ccrypto
|
|
130
185
|
end
|
131
186
|
end
|
132
187
|
|
133
|
-
class DirectCipherConfig < CipherConfig
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
end
|
144
|
-
|
145
|
-
class CipherEngineConfig < CipherConfig
|
146
|
-
|
147
|
-
|
148
|
-
end
|
188
|
+
#class DirectCipherConfig < CipherConfig
|
189
|
+
# # str can be String or Hash
|
190
|
+
# # If String it will be directly used by underlying
|
191
|
+
# # engine with minimum parsing which means might not have other
|
192
|
+
# # info
|
193
|
+
# def initialize(str)
|
194
|
+
# raise CipherConfigException, "Hash is expected" if not str.is_a?(Hash)
|
195
|
+
# super(str[:algo], str)
|
196
|
+
# end
|
197
|
+
|
198
|
+
#end
|
199
|
+
|
200
|
+
#class CipherEngineConfig < CipherConfig
|
201
|
+
# # engine that is discovered by cipher engine
|
202
|
+
# # Means can directly use the object
|
203
|
+
#end
|
149
204
|
|
150
205
|
end
|
@@ -41,6 +41,7 @@ module Ccrypto
|
|
41
41
|
# https://stackoverflow.com/a/33297994/3625825
|
42
42
|
|
43
43
|
def initialize
|
44
|
+
@algo = :scrypt
|
44
45
|
@cost = 16384 # 2**14
|
45
46
|
@blockSize = 8
|
46
47
|
@parallel = 1
|
@@ -51,17 +52,57 @@ module Ccrypto
|
|
51
52
|
class HKDFConfig < KDFConfig
|
52
53
|
attr_accessor :salt, :info, :digest
|
53
54
|
def initialize
|
55
|
+
@algo = :hkdf
|
54
56
|
@salt = SecureRandom.random_bytes(16)
|
55
|
-
@digest = :
|
57
|
+
@digest = :sha3_256
|
56
58
|
end
|
57
59
|
end
|
58
60
|
|
59
61
|
class PBKDF2Config < KDFConfig
|
60
62
|
attr_accessor :salt, :digest, :iter
|
61
63
|
def initialize
|
64
|
+
@algo = :pbkdf2
|
62
65
|
@salt = SecureRandom.random_bytes(16)
|
63
|
-
@digest = :
|
64
|
-
@iter = rand(
|
66
|
+
@digest = :sha3_256
|
67
|
+
@iter = rand(300000..500000)
|
65
68
|
end
|
66
69
|
end
|
70
|
+
|
71
|
+
class Argon2Config < KDFConfig
|
72
|
+
|
73
|
+
attr_accessor :cost, :salt, :secret, :parallel, :iter
|
74
|
+
attr_accessor :variant
|
75
|
+
|
76
|
+
def initialize
|
77
|
+
|
78
|
+
@algo = :argon2
|
79
|
+
|
80
|
+
# "salt" which can be stored non-secure or with the password Hash
|
81
|
+
@salt = SecureRandom.random_bytes(16)
|
82
|
+
|
83
|
+
# Secret value which has to be stored in a different secure location from the password hashes
|
84
|
+
@secret = SecureRandom.random_bytes(16)
|
85
|
+
|
86
|
+
# The RFC recommends 4 GB for backend authentication and 1 GB for frontend authentication.
|
87
|
+
@cost = 1*1024*1024*1024
|
88
|
+
|
89
|
+
# Choose the Number of CPU-Threads you can afford each call (2 Cores = 4 Threads)
|
90
|
+
@parallel = 4
|
91
|
+
|
92
|
+
# Set the number of Iterations each call -> More Iterations = Better Security + more Hashing Time
|
93
|
+
# > 3 Iterations recommended
|
94
|
+
@iter = 3
|
95
|
+
|
96
|
+
# Follow BC library
|
97
|
+
# Argon2d
|
98
|
+
# Argon2i (recommended)
|
99
|
+
# Argon2id
|
100
|
+
# Argon2_version_10
|
101
|
+
# Argon2_version_13
|
102
|
+
@variant = :argon2i
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
67
108
|
end
|
@@ -1,11 +1,32 @@
|
|
1
1
|
|
2
2
|
|
3
3
|
module Ccrypto
|
4
|
+
|
4
5
|
class KeypairConfig
|
5
6
|
include AlgoConfig
|
6
7
|
|
7
8
|
attr_accessor :algo
|
8
9
|
attr_accessor :keypair, :private_key, :public_key
|
10
|
+
|
11
|
+
attr_reader :algo_status
|
12
|
+
|
13
|
+
Algo_Active = :active
|
14
|
+
Algo_NotRecommended = :not_recommended
|
15
|
+
Algo_Obsolete = :obsolete
|
16
|
+
Algo_Broken = :broken
|
17
|
+
|
18
|
+
attr_reader :default
|
19
|
+
|
20
|
+
attr_accessor :native_config
|
21
|
+
|
22
|
+
def initialize(status = Algo_Active, default = false)
|
23
|
+
@algo_status = status
|
24
|
+
@default = default
|
25
|
+
end
|
26
|
+
|
27
|
+
def is_default_algo?
|
28
|
+
@default
|
29
|
+
end
|
9
30
|
|
10
31
|
def has_keypair?
|
11
32
|
(not @keypair.nil?) or not (@privateKey.nil? and @publicKey.nil?)
|
@@ -26,29 +47,85 @@ module Ccrypto
|
|
26
47
|
not @public_key.nil?
|
27
48
|
end
|
28
49
|
end
|
29
|
-
|
50
|
+
|
51
|
+
def self.keypair_purposes
|
52
|
+
{
|
53
|
+
signing: "Keypair for signing and digital signature operation",
|
54
|
+
cipher: "Keypair for data encryption operation",
|
55
|
+
sign_and_encrypt: "Keypair for both signing and data encryption operation"
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.supported_keypair_config(purpose = :signing, &block)
|
60
|
+
Provider.instance.provider.supported_keypair_config(purpose, &block)
|
61
|
+
end
|
62
|
+
|
63
|
+
end # KeypairConfig
|
30
64
|
|
31
65
|
class ECCConfig < KeypairConfig
|
66
|
+
|
67
|
+
def self.name
|
68
|
+
"Elliptic Curve (ECC)"
|
69
|
+
end
|
70
|
+
|
32
71
|
attr_accessor :curve
|
33
|
-
def initialize(curve = nil)
|
72
|
+
def initialize(curve = nil, status = Algo_Active, default = false)
|
34
73
|
@algo = :ecc
|
35
74
|
@curve = curve || :prime256v1
|
75
|
+
@curve = @curve.to_sym if not @curve.is_a?(Symbol)
|
76
|
+
super(status, default)
|
36
77
|
end
|
37
78
|
|
38
79
|
def to_s
|
39
|
-
"
|
80
|
+
"#{@curve}"
|
40
81
|
end
|
41
|
-
|
82
|
+
|
83
|
+
def self.supported_curves(&block)
|
84
|
+
Provider.instance.provider.algo_instance(*[ECCConfig], &block).supported_curves
|
85
|
+
end
|
86
|
+
end # ECCConfig
|
42
87
|
|
43
88
|
class RSAConfig < KeypairConfig
|
89
|
+
def self.name
|
90
|
+
"RSA"
|
91
|
+
end
|
92
|
+
|
44
93
|
attr_accessor :keysize
|
45
|
-
def initialize(keysize = 2048)
|
94
|
+
def initialize(keysize = 2048, status = Algo_Active, default = false)
|
46
95
|
@keysize = keysize
|
96
|
+
super(status, default)
|
47
97
|
end
|
48
98
|
|
49
99
|
def to_s
|
50
100
|
"RSA-#{keysize} bits"
|
51
101
|
end
|
102
|
+
|
103
|
+
def self.supported_keysizes(&block)
|
104
|
+
Provider.instance.provider.algo_instance(*[RSAConfig],&block).supported_keysizes
|
105
|
+
end
|
106
|
+
end # RSAConfig
|
107
|
+
|
108
|
+
# ED25519 for data signature
|
109
|
+
class ED25519Config < KeypairConfig
|
110
|
+
def self.name
|
111
|
+
"ED25519 (Signing Only)"
|
112
|
+
end
|
113
|
+
|
114
|
+
def initialize
|
115
|
+
algo = :ed25519
|
116
|
+
super(Algo_Active, true)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# X25519 for key exchange
|
121
|
+
class X25519Config < KeypairConfig
|
122
|
+
def self.name
|
123
|
+
"X25519 (Data Encipherment only)"
|
124
|
+
end
|
125
|
+
def initialize
|
126
|
+
algo = :x25519
|
127
|
+
super(Algo_Active, true)
|
128
|
+
end
|
52
129
|
end
|
53
130
|
|
54
131
|
end
|
@@ -15,13 +15,17 @@ module Ccrypto
|
|
15
15
|
|
16
16
|
attr_accessor :owner_name, :org
|
17
17
|
attr_accessor :org_unit, :email, :dns_name, :ip_addr, :uri
|
18
|
-
attr_accessor :
|
18
|
+
attr_accessor :locality, :country
|
19
|
+
attr_accessor :public_key, :serial # , :not_before, :not_after
|
20
|
+
attr_accessor :csr
|
19
21
|
attr_accessor :subj_key_id, :auth_key_id
|
20
22
|
attr_accessor :crl_dist_point, :ocsp_url, :issuer_url
|
21
23
|
attr_accessor :issuer_cert
|
22
24
|
attr_accessor :hashAlgo
|
23
25
|
attr_accessor :raise_if_validity_date_not_in_issuer_range
|
24
26
|
|
27
|
+
attr_accessor :issuer_path_len
|
28
|
+
|
25
29
|
def initialize
|
26
30
|
@hashAlgo = Ccrypto::SHA256
|
27
31
|
@serial = SecureRandom.hex(16)
|
@@ -34,6 +38,28 @@ module Ccrypto
|
|
34
38
|
@raise_if_validity_date_not_in_issuer_range = false
|
35
39
|
end
|
36
40
|
|
41
|
+
def not_before=(val)
|
42
|
+
@not_before = val
|
43
|
+
end
|
44
|
+
alias_method :valid_from=, :not_before=
|
45
|
+
|
46
|
+
def not_before
|
47
|
+
@not_before
|
48
|
+
end
|
49
|
+
alias_method :valid_from, :not_before
|
50
|
+
|
51
|
+
def not_after=(val)
|
52
|
+
@not_after = val
|
53
|
+
end
|
54
|
+
alias_method :valid_until=, :not_after=
|
55
|
+
alias_method :valid_to=, :not_after=
|
56
|
+
|
57
|
+
def not_after
|
58
|
+
@not_after
|
59
|
+
end
|
60
|
+
alias_method :valid_until, :not_after
|
61
|
+
alias_method :valid_to, :not_after
|
62
|
+
|
37
63
|
def gen_issuer_cert?
|
38
64
|
@issuerCert
|
39
65
|
end
|
@@ -65,6 +91,18 @@ module Ccrypto
|
|
65
91
|
end
|
66
92
|
end
|
67
93
|
|
94
|
+
def email=(val)
|
95
|
+
if @email.nil?
|
96
|
+
@email = []
|
97
|
+
end
|
98
|
+
|
99
|
+
case val
|
100
|
+
when Array
|
101
|
+
@email += val
|
102
|
+
else
|
103
|
+
@email << val
|
104
|
+
end
|
105
|
+
end
|
68
106
|
def email
|
69
107
|
if @email.nil?
|
70
108
|
[]
|
@@ -75,6 +113,18 @@ module Ccrypto
|
|
75
113
|
end
|
76
114
|
end
|
77
115
|
|
116
|
+
def dns_name=(val)
|
117
|
+
if @dns_name.nil?
|
118
|
+
@dns_name = []
|
119
|
+
end
|
120
|
+
|
121
|
+
case val
|
122
|
+
when Array
|
123
|
+
@dns_name += val
|
124
|
+
else
|
125
|
+
@dns_name << val
|
126
|
+
end
|
127
|
+
end
|
78
128
|
def dns_name
|
79
129
|
if @dns_name.nil?
|
80
130
|
[]
|
@@ -85,6 +135,19 @@ module Ccrypto
|
|
85
135
|
end
|
86
136
|
end
|
87
137
|
|
138
|
+
|
139
|
+
def ip_addr=(val)
|
140
|
+
if @ip_addr.nil?
|
141
|
+
@ip_addr = []
|
142
|
+
end
|
143
|
+
|
144
|
+
case val
|
145
|
+
when Array
|
146
|
+
@ip_addr += val
|
147
|
+
else
|
148
|
+
@ip_addr << val
|
149
|
+
end
|
150
|
+
end
|
88
151
|
def ip_addr
|
89
152
|
if @ip_addr.nil?
|
90
153
|
[]
|
@@ -95,6 +158,19 @@ module Ccrypto
|
|
95
158
|
end
|
96
159
|
end
|
97
160
|
|
161
|
+
def uri=(val)
|
162
|
+
if @uri.nil?
|
163
|
+
@uri = []
|
164
|
+
end
|
165
|
+
|
166
|
+
case val
|
167
|
+
when Array
|
168
|
+
@uri += val
|
169
|
+
else
|
170
|
+
@uri << val
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
98
174
|
def uri
|
99
175
|
if @uri.nil?
|
100
176
|
[]
|
@@ -236,8 +312,8 @@ module Ccrypto
|
|
236
312
|
clientAuth: "TLS client authentication",
|
237
313
|
codeSigning: "Code signing",
|
238
314
|
emailProtection: "Email protection",
|
239
|
-
|
240
|
-
|
315
|
+
timeStamping: "Time stamping",
|
316
|
+
OCSPSigning: "Online Cert Status Protocol signing",
|
241
317
|
ipSecIKE: "IPSec Initial Key Exchange",
|
242
318
|
msCodeInd: "Microsoft Code Ind",
|
243
319
|
msCodeCom: "Microsoft Code Com",
|
@@ -292,6 +368,17 @@ module Ccrypto
|
|
292
368
|
@domainKeyUsage
|
293
369
|
end
|
294
370
|
|
371
|
+
def add_custom_extension(oid, value, type = :string, critical = false)
|
372
|
+
custom_extension[oid] = { type: type, value: value, critical: critical }
|
373
|
+
end
|
374
|
+
|
375
|
+
def custom_extension
|
376
|
+
if @custom_extension.nil?
|
377
|
+
@custom_extension = { }
|
378
|
+
end
|
379
|
+
@custom_extension
|
380
|
+
end
|
381
|
+
|
295
382
|
end
|
296
383
|
end
|
297
384
|
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
|
2
|
+
require_relative 'algo_config'
|
3
|
+
|
4
|
+
module Ccrypto
|
5
|
+
module X509
|
6
|
+
class CSRProfile
|
7
|
+
include Ccrypto::AlgoConfig
|
8
|
+
include TR::CondUtils
|
9
|
+
|
10
|
+
include TeLogger::TeLogHelper
|
11
|
+
teLogger_tag :csr
|
12
|
+
|
13
|
+
attr_accessor :owner_name, :org
|
14
|
+
attr_accessor :org_unit, :email, :dns_name, :ip_addr, :uri
|
15
|
+
attr_accessor :public_key
|
16
|
+
attr_accessor :hashAlgo
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@hashAlgo = Ccrypto::SHA256
|
20
|
+
end
|
21
|
+
|
22
|
+
def org_unit
|
23
|
+
if @org_unit.nil?
|
24
|
+
[]
|
25
|
+
elsif not @org_unit.is_a?(Array)
|
26
|
+
[@org_unit]
|
27
|
+
else
|
28
|
+
@org_unit
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def email=(val)
|
33
|
+
if @email.nil?
|
34
|
+
@email = []
|
35
|
+
end
|
36
|
+
|
37
|
+
case val
|
38
|
+
when Array
|
39
|
+
@email += val
|
40
|
+
else
|
41
|
+
@email << val
|
42
|
+
end
|
43
|
+
end
|
44
|
+
def email
|
45
|
+
if @email.nil?
|
46
|
+
[]
|
47
|
+
elsif not @email.is_a?(Array)
|
48
|
+
[@email]
|
49
|
+
else
|
50
|
+
@email
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def dns_name=(val)
|
55
|
+
if @dns_name.nil?
|
56
|
+
@dns_name = []
|
57
|
+
end
|
58
|
+
|
59
|
+
case val
|
60
|
+
when Array
|
61
|
+
@dns_name += val
|
62
|
+
else
|
63
|
+
@dns_name << val
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def dns_name
|
68
|
+
if @dns_name.nil?
|
69
|
+
[]
|
70
|
+
elsif not @dns_name.is_a?(Array)
|
71
|
+
[@dns_name]
|
72
|
+
else
|
73
|
+
@dns_name
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def ip_addr=(val)
|
79
|
+
if @ip_addr.nil?
|
80
|
+
@ip_addr = []
|
81
|
+
end
|
82
|
+
|
83
|
+
case val
|
84
|
+
when Array
|
85
|
+
@ip_addr += val
|
86
|
+
else
|
87
|
+
@ip_addr << val
|
88
|
+
end
|
89
|
+
end
|
90
|
+
def ip_addr
|
91
|
+
if @ip_addr.nil?
|
92
|
+
[]
|
93
|
+
elsif not @ip_addr.is_a?(Array)
|
94
|
+
[@ip_addr]
|
95
|
+
else
|
96
|
+
@ip_addr
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def uri=(val)
|
101
|
+
if @uri.nil?
|
102
|
+
@uri = []
|
103
|
+
end
|
104
|
+
|
105
|
+
case val
|
106
|
+
when Array
|
107
|
+
@uri += val
|
108
|
+
else
|
109
|
+
@uri << val
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def uri
|
114
|
+
if @uri.nil?
|
115
|
+
[]
|
116
|
+
elsif not @uri.is_a?(Array)
|
117
|
+
[@uri]
|
118
|
+
else
|
119
|
+
@uri
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def add_custom_attribute(key,value, type = :string)
|
124
|
+
additional_attributes[key] = { value: value, type: type }
|
125
|
+
end
|
126
|
+
|
127
|
+
def additional_attributes
|
128
|
+
if @addAttr.nil?
|
129
|
+
@addAttr = {}
|
130
|
+
end
|
131
|
+
@addAttr
|
132
|
+
end
|
133
|
+
|
134
|
+
def add_custom_extension(oid, value, type = :string, critical = false)
|
135
|
+
custom_extension[oid] = { type: type, value: value, critical: critical }
|
136
|
+
end
|
137
|
+
|
138
|
+
def custom_extension
|
139
|
+
if @custom_extension.nil?
|
140
|
+
@custom_extension = { }
|
141
|
+
end
|
142
|
+
@custom_extension
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
data/lib/ccrypto/key_bundle.rb
CHANGED
@@ -3,6 +3,11 @@
|
|
3
3
|
module Ccrypto
|
4
4
|
module KeyBundle
|
5
5
|
attr_accessor :nativeKeypair
|
6
|
+
|
7
|
+
def KeyBundle.from_storage(*args, &block)
|
8
|
+
Provider.instance.provider.keybundle_from_storage(*args, &block)
|
9
|
+
end
|
10
|
+
|
6
11
|
end
|
7
12
|
|
8
13
|
module ECCKeyBundle
|
@@ -12,4 +17,12 @@ module Ccrypto
|
|
12
17
|
module RSAKeyBundle
|
13
18
|
include KeyBundle
|
14
19
|
end
|
20
|
+
|
21
|
+
module ED25519KeyBundle
|
22
|
+
include KeyBundle
|
23
|
+
end
|
24
|
+
|
25
|
+
module X25519KeyBundle
|
26
|
+
include KeyBundle
|
27
|
+
end
|
15
28
|
end
|
data/lib/ccrypto/private_key.rb
CHANGED
data/lib/ccrypto/public_key.rb
CHANGED
@@ -0,0 +1,141 @@
|
|
1
|
+
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
module Ccrypto
|
5
|
+
|
6
|
+
class SupportedCipherListError < StandardError; end
|
7
|
+
|
8
|
+
class SupportedCipherList
|
9
|
+
include TR::CondUtils
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
include TeLogger::TeLogHelper
|
13
|
+
teLogger_tag :supCipherList
|
14
|
+
|
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] = [] if @modes[mode].nil?
|
42
|
+
@modes[mode] << 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.freeze
|
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
|
+
res = @algos[algo.to_sym] || []
|
79
|
+
res.freeze
|
80
|
+
end
|
81
|
+
|
82
|
+
# Problem with this is the algo is in symbol
|
83
|
+
# and external app need to remember to conver it to
|
84
|
+
# symbol in order to compare.
|
85
|
+
# therefore the new method is_algo_supported? created
|
86
|
+
# to solve this issue
|
87
|
+
def algos
|
88
|
+
@algos.keys.freeze
|
89
|
+
end
|
90
|
+
|
91
|
+
def is_algo_supported?(algo)
|
92
|
+
@algos.keys.include?(algo.to_sym)
|
93
|
+
end
|
94
|
+
|
95
|
+
def keysizes_count
|
96
|
+
@keysizes.length
|
97
|
+
end
|
98
|
+
def keysizes
|
99
|
+
@keysizes.keys.freeze
|
100
|
+
end
|
101
|
+
def find_config_by_keysize(keysize)
|
102
|
+
@keysizes[keysize.to_s].freeze
|
103
|
+
end
|
104
|
+
|
105
|
+
def mode_count
|
106
|
+
@modes.length
|
107
|
+
end
|
108
|
+
def find_config_by_mode(mode)
|
109
|
+
@modes[mode.to_s].freeze
|
110
|
+
end
|
111
|
+
def modes
|
112
|
+
@modes.keys.freeze
|
113
|
+
end
|
114
|
+
|
115
|
+
def find_algo_keysize(algo, keysize)
|
116
|
+
res = @algoKeysize[algo.to_sym] || { }
|
117
|
+
res = res[keysize.to_s] || []
|
118
|
+
res.freeze
|
119
|
+
end
|
120
|
+
|
121
|
+
def find_algo_mode(algo, mode)
|
122
|
+
res = @algoMode[algo.to_sym] || {}
|
123
|
+
res = res[mode.to_s] || []
|
124
|
+
res.freeze
|
125
|
+
end
|
126
|
+
|
127
|
+
def find_algo_keysize_mode(algo, keysize, mode)
|
128
|
+
res = @algoKeysizeMode[algo.to_sym] || {}
|
129
|
+
res = res[keysize.to_s] || {}
|
130
|
+
res = res[mode.to_s] || []
|
131
|
+
res.freeze
|
132
|
+
end
|
133
|
+
|
134
|
+
def find_keysize_modes(keysize, mode)
|
135
|
+
res = @keysizeMode[keysize.to_s] || {}
|
136
|
+
res = res[mode.to_s] || []
|
137
|
+
res.freeze
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
data/lib/ccrypto/version.rb
CHANGED
data/lib/ccrypto.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'toolrack'
|
4
|
-
require '
|
4
|
+
require 'teLogger'
|
5
5
|
|
6
6
|
require_relative "ccrypto/version"
|
7
7
|
|
8
8
|
require_relative 'ccrypto/provider'
|
9
9
|
require_relative 'ccrypto/algo_factory'
|
10
10
|
require_relative 'ccrypto/key_bundle'
|
11
|
+
require_relative 'ccrypto/supported_cipher_list'
|
11
12
|
|
12
13
|
require_relative 'ccrypto/asn1'
|
13
14
|
require_relative 'ccrypto/asn1_object'
|
@@ -23,6 +24,7 @@ require_relative 'ccrypto/private_key'
|
|
23
24
|
require_relative 'ccrypto/secret_key'
|
24
25
|
|
25
26
|
require_relative 'ccrypto/x509_cert'
|
27
|
+
require_relative 'ccrypto/x509_csr'
|
26
28
|
|
27
29
|
module Ccrypto
|
28
30
|
class Error < StandardError; end
|
@@ -34,6 +36,10 @@ module Ccrypto
|
|
34
36
|
class KeypairEngineException < StandardError; end
|
35
37
|
class KeyBundleException < StandardError; end
|
36
38
|
class X509EngineException < StandardError; end
|
39
|
+
|
40
|
+
class X509CSRException < StandardError; end
|
41
|
+
class X509CSRSignatureInvalid < StandardError; end
|
42
|
+
|
37
43
|
class CipherEngineException < StandardError; end
|
38
44
|
class ASN1EngineException < StandardError; end
|
39
45
|
|
@@ -50,4 +56,7 @@ module Ccrypto
|
|
50
56
|
|
51
57
|
class KeyBundleStorageException < StandardError; end
|
52
58
|
# Your code goes here...
|
59
|
+
|
60
|
+
Root_OID = ["2","0","18"]
|
61
|
+
|
53
62
|
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.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: teLogger
|
@@ -66,13 +66,15 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description:
|
69
|
+
description: Attempt to have a common crypto for Ruby and Java to take the selection
|
70
|
+
decision out from the application development until further date
|
70
71
|
email:
|
71
72
|
- cameronian0@protonmail.com
|
72
73
|
executables: []
|
73
74
|
extensions: []
|
74
75
|
extra_rdoc_files: []
|
75
76
|
files:
|
77
|
+
- ".release_history.yml"
|
76
78
|
- ".rspec"
|
77
79
|
- Gemfile
|
78
80
|
- Gemfile.lock
|
@@ -97,14 +99,17 @@ files:
|
|
97
99
|
- lib/ccrypto/configs/secret_sharing_config.rb
|
98
100
|
- lib/ccrypto/configs/secure_random_config.rb
|
99
101
|
- lib/ccrypto/configs/x509_cert_profile.rb
|
102
|
+
- lib/ccrypto/configs/x509_csr_profile.rb
|
100
103
|
- lib/ccrypto/key_bundle.rb
|
101
104
|
- lib/ccrypto/private_key.rb
|
102
105
|
- lib/ccrypto/provider.rb
|
103
106
|
- lib/ccrypto/public_key.rb
|
104
107
|
- lib/ccrypto/secret_key.rb
|
108
|
+
- lib/ccrypto/supported_cipher_list.rb
|
105
109
|
- lib/ccrypto/util_factory.rb
|
106
110
|
- lib/ccrypto/version.rb
|
107
111
|
- lib/ccrypto/x509_cert.rb
|
112
|
+
- lib/ccrypto/x509_csr.rb
|
108
113
|
homepage: https://github.com/cameronian/ccrypto
|
109
114
|
licenses: []
|
110
115
|
metadata: {}
|
@@ -123,8 +128,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
128
|
- !ruby/object:Gem::Version
|
124
129
|
version: '0'
|
125
130
|
requirements: []
|
126
|
-
rubygems_version: 3.
|
131
|
+
rubygems_version: 3.4.10
|
127
132
|
signing_key:
|
128
133
|
specification_version: 4
|
129
|
-
summary:
|
134
|
+
summary: Crypto API normalization for Ruby and Java
|
130
135
|
test_files: []
|