ccrypto 0.1.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,54 @@
1
+
2
+
3
+ module Ccrypto
4
+ class KeypairConfig
5
+ include AlgoConfig
6
+
7
+ attr_accessor :algo
8
+ attr_accessor :keypair, :private_key, :public_key
9
+
10
+ def has_keypair?
11
+ (not @keypair.nil?) or not (@privateKey.nil? and @publicKey.nil?)
12
+ end
13
+
14
+ def has_private_key?
15
+ if has_keypair?
16
+ not @keypair.private_key.nil?
17
+ else
18
+ not @private_key.nil?
19
+ end
20
+ end
21
+
22
+ def has_public_key?
23
+ if has_keypair?
24
+ not @keypair.public_key.nil?
25
+ else
26
+ not @public_key.nil?
27
+ end
28
+ end
29
+ end
30
+
31
+ class ECCConfig < KeypairConfig
32
+ attr_accessor :curve
33
+ def initialize(curve = nil)
34
+ @algo = :ecc
35
+ @curve = curve || :prime256v1
36
+ end
37
+
38
+ def to_s
39
+ "ECC-#{@curve}"
40
+ end
41
+ end
42
+
43
+ class RSAConfig < KeypairConfig
44
+ attr_accessor :keysize
45
+ def initialize(keysize = 2048)
46
+ @keysize = keysize
47
+ end
48
+
49
+ def to_s
50
+ "RSA-#{keysize} bits"
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,32 @@
1
+
2
+
3
+ module Ccrypto
4
+ class PKCS7Config
5
+ include AlgoConfig
6
+ include TR::CondUtils
7
+
8
+ #attr_accessor :keybundle
9
+
10
+ attr_accessor :private_key, :public_key
11
+ # for signing operation
12
+ attr_accessor :signerCert
13
+ # for decryption operation
14
+ attr_accessor :certForDecryption
15
+
16
+ def add_recipient_cert(cert)
17
+ recpCerts << cert if not_empty?(cert)
18
+ end
19
+
20
+ def recipient_certs
21
+ recpCerts
22
+ end
23
+
24
+ protected
25
+ def recpCerts
26
+ if @recpCerts.nil?
27
+ @recpCerts = []
28
+ end
29
+ @recpCerts
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+
2
+
3
+ module Ccrypto
4
+ class SecretSharingConfig
5
+ include AlgoConfig
6
+
7
+ attr_accessor :split_into
8
+ attr_accessor :required_parts
9
+
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+
2
+
3
+ module Ccrypto
4
+ class SecureRandomConfig
5
+ include AlgoConfig
6
+ end
7
+ end
@@ -0,0 +1,297 @@
1
+
2
+ require 'active_support'
3
+ require 'active_support/core_ext/time'
4
+
5
+ module Ccrypto
6
+ module X509
7
+ class CertProfile
8
+ include Ccrypto::AlgoConfig
9
+ include TR::CondUtils
10
+
11
+ include TeLogger::TeLogHelper
12
+ teLogger_tag :cert_prof
13
+
14
+ class CertProfileException < StandardError; end
15
+
16
+ attr_accessor :owner_name, :org
17
+ attr_accessor :org_unit, :email, :dns_name, :ip_addr, :uri
18
+ attr_accessor :public_key, :serial, :not_before, :not_after
19
+ attr_accessor :subj_key_id, :auth_key_id
20
+ attr_accessor :crl_dist_point, :ocsp_url, :issuer_url
21
+ attr_accessor :issuer_cert
22
+ attr_accessor :hashAlgo
23
+ attr_accessor :raise_if_validity_date_not_in_issuer_range
24
+
25
+ def initialize
26
+ @hashAlgo = Ccrypto::SHA256
27
+ @serial = SecureRandom.hex(16)
28
+ @subj_key_id = true
29
+ @auth_key_id = true
30
+ @issuerCert = false
31
+ now = Time.now
32
+ @not_before = Time.new(now.year, now.month, now.day)
33
+ @not_after = Time.new(now.year+2, now.month, now.day)
34
+ @raise_if_validity_date_not_in_issuer_range = false
35
+ end
36
+
37
+ def gen_issuer_cert?
38
+ @issuerCert
39
+ end
40
+ def gen_issuer_cert=(val)
41
+ @issuerCert = val
42
+ end
43
+
44
+ def gen_subj_key_id?
45
+ @subj_key_id
46
+ end
47
+ def gen_subj_key_id=(val)
48
+ @subj_key_id = val
49
+ end
50
+
51
+ def gen_auth_key_id?
52
+ @auth_key_id
53
+ end
54
+ def gen_auth_key_id=(val)
55
+ @auth_key_id = val
56
+ end
57
+
58
+ def org_unit
59
+ if @org_unit.nil?
60
+ []
61
+ elsif not @org_unit.is_a?(Array)
62
+ [@org_unit]
63
+ else
64
+ @org_unit
65
+ end
66
+ end
67
+
68
+ def email
69
+ if @email.nil?
70
+ []
71
+ elsif not @email.is_a?(Array)
72
+ [@email]
73
+ else
74
+ @email
75
+ end
76
+ end
77
+
78
+ def dns_name
79
+ if @dns_name.nil?
80
+ []
81
+ elsif not @dns_name.is_a?(Array)
82
+ [@dns_name]
83
+ else
84
+ @dns_name
85
+ end
86
+ end
87
+
88
+ def ip_addr
89
+ if @ip_addr.nil?
90
+ []
91
+ elsif not @ip_addr.is_a?(Array)
92
+ [@ip_addr]
93
+ else
94
+ @ip_addr
95
+ end
96
+ end
97
+
98
+ def uri
99
+ if @uri.nil?
100
+ []
101
+ elsif not @uri.is_a?(Array)
102
+ [@uri]
103
+ else
104
+ @uri
105
+ end
106
+ end
107
+
108
+ def crl_dist_point
109
+ if @crl_dist_point.nil?
110
+ []
111
+ elsif not @crl_dist_point.is_a?(Array)
112
+ [@crl_dist_point]
113
+ else
114
+ @crl_dist_point
115
+ end
116
+ end
117
+
118
+ def ocsp_url
119
+ if @ocsp_url.nil?
120
+ []
121
+ elsif not @ocsp_url.is_a?(Array)
122
+ [@ocsp_url]
123
+ else
124
+ @ocsp_url
125
+ end
126
+ end
127
+
128
+ def issuer_url
129
+ if @issuer_url.nil?
130
+ []
131
+ elsif not @issuer_url.is_a?(Array)
132
+ [@issuer_url]
133
+ else
134
+ @issuer_url
135
+ end
136
+ end
137
+
138
+ def validity(qty, unit = :years)
139
+
140
+ raise CertProfileException, "not_before has to set before validity can be set" if is_empty?(@not_before)
141
+
142
+ case unit
143
+ when :days, :day
144
+ adv = { days: qty }
145
+ when :months, :month
146
+ adv = { months: qty }
147
+ when :weeks, :week
148
+ adv = { weeks: qty }
149
+ when :years, :year
150
+ adv = { years: qty }
151
+ else
152
+ raise CertProfileException, "Unknown unit '#{unit}'"
153
+ end
154
+
155
+ @not_after = @not_before.advance(adv)
156
+
157
+ end
158
+
159
+ def match_issuer_not_before(issuer_not_before)
160
+ if not_empty?(issuer_not_before)
161
+ if issuer_not_before.is_a?(Time)
162
+ if issuer_not_before > @not_before
163
+ if @raise_if_validity_date_not_in_issuer_range
164
+ raise X509CertNotBeforeException, "Issuer not_before '#{issuer_not_before.localtime}' > To-be-signed cert not_before '#{@not_before.localtime}'"
165
+ else
166
+ teLogger.info "Issuer has not_before at #{issuer_not_before.localtime} but to-be-signed certificate has not_before at #{@not_before.localtime}. To-be-signed certificate cannot has not_before earlier than issuer not_before. Auto adjusting the to-be-signed certificate to #{issuer_not_before.localtime}."
167
+ @not_before = issuer_not_before
168
+ end
169
+ else
170
+ teLogger.debug "to-be-signed certificate has valid not_before value (#{@not_before}) : after issuer not_before (#{issuer_not_before})"
171
+ end
172
+ else
173
+ teLogger.warn "issuer_not_before is not a Time object. It is a '#{issuer_not_before.class}'"
174
+ end
175
+ end
176
+ end
177
+
178
+ def match_issuer_not_after(issuer_not_after)
179
+ if not_empty?(issuer_not_after)
180
+ if issuer_not_after.is_a?(Time)
181
+ if @not_after > issuer_not_after
182
+ if @raise_if_validity_date_not_in_issuer_range
183
+ raise X509CertNotAfterException, "Issuer not_after '#{issuer_not_after.localtime}' < To-be-signed cert not_after '#{@not_after.localtime}'"
184
+ else
185
+ teLogger.info "Issuer has not_after at #{issuer_not_after.localtime} but to-be-signed certificate has not_after at #{@not_after.localtime}. To-be-signed certificate cannot has not_after later than issuer not_after. Auto adjusting the to-be-signed certificate to #{issuer_not_after.localtime}."
186
+ @not_after = issuer_not_after
187
+ end
188
+ else
189
+ teLogger.debug "to-be-signed certificate has valid not_after value (#{@not_after}): before issuer not_after (#{issuer_not_after})"
190
+ end
191
+ else
192
+ teLogger.warn "issuer_not_after is not a Time object. It is a '#{issuer_not_after.class}'"
193
+ end
194
+ end
195
+ end
196
+
197
+ class KeyUsage
198
+ #Key = [:digitalSignature, :nonRepudiation, :keyEncipherment, :dataEncipherment, :keyAgreement, :keyCertSign, :crlSign, :encipherOnly, :decipherOnly]
199
+ Usages = {
200
+ digitalSignature: "Digital signature",
201
+ nonRepudiation: "Non Repudiation",
202
+ keyEncipherment: "Key encipherment",
203
+ dataEncipherment: "Data encipherment",
204
+ keyAgreement: "Key agreement",
205
+ keyCertSign: "Sign/Issue certificate",
206
+ crlSign: "Sign/Issue Certificate Revocation List (CRL)",
207
+ encipherOnly: "Data encipherment only",
208
+ decipherOnly: "Data decipherment only",
209
+ }
210
+
211
+ def initialize
212
+ @selected = { }
213
+ end
214
+
215
+ def selected
216
+ @selected
217
+ end
218
+
219
+ Usages.keys.each do |k|
220
+ class_eval <<-END
221
+ def enable_#{k}(critical = false)
222
+ @selected[:#{k}] = critical
223
+ self
224
+ end
225
+ END
226
+ end
227
+
228
+ end # KeyUsage
229
+
230
+
231
+ class ExtKeyUsage
232
+ #Key = [:allPurpose, :serverAuth, :clientAuth, :codeSigning, :emailProtection, :timestamping, :ocspSigning, :ipSecIKE, :msCodeInd, :msCodeCom, :msCtlsign, :msEFS, :dvcs]
233
+ Usages = {
234
+ allPurpose: "All extended key usages",
235
+ serverAuth: "TLS server authentication",
236
+ clientAuth: "TLS client authentication",
237
+ codeSigning: "Code signing",
238
+ emailProtection: "Email protection",
239
+ timestamping: "Time stamping",
240
+ ocspSigning: "Online Cert Status Protocol signing",
241
+ ipSecIKE: "IPSec Initial Key Exchange",
242
+ msCodeInd: "Microsoft Code Ind",
243
+ msCodeCom: "Microsoft Code Com",
244
+ msCtlsign: "Microsoft CTL Sign",
245
+ msEFS: "Microsoft EFS",
246
+ dvcs: "DVCS purposes"
247
+ }
248
+
249
+
250
+ def initialize
251
+ @selected = { }
252
+ end
253
+
254
+ def selected
255
+ @selected
256
+ end
257
+
258
+ Usages.keys.each do |k|
259
+ class_eval <<-END
260
+ def enable_#{k}(critical = false)
261
+ @selected[:#{k}] = critical
262
+ self
263
+ end
264
+ END
265
+ end
266
+
267
+
268
+ end #extKeyUsage
269
+
270
+ def key_usage
271
+ if @keyUsage.nil?
272
+ @keyUsage = KeyUsage.new
273
+ end
274
+ @keyUsage
275
+ end
276
+
277
+ def ext_key_usage
278
+ if @extKeyUsage.nil?
279
+ @extKeyUsage = ExtKeyUsage.new
280
+ end
281
+ @extKeyUsage
282
+ end
283
+
284
+ def add_domain_key_usage(oid, critical = false)
285
+ domain_key_usage[oid] = critical
286
+ end
287
+
288
+ def domain_key_usage
289
+ if @domainKeyUsage.nil?
290
+ @domainKeyUsage = { }
291
+ end
292
+ @domainKeyUsage
293
+ end
294
+
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,15 @@
1
+
2
+
3
+ module Ccrypto
4
+ module KeyBundle
5
+ attr_accessor :nativeKeypair
6
+ end
7
+
8
+ module ECCKeyBundle
9
+ include KeyBundle
10
+ end
11
+
12
+ module RSAKeyBundle
13
+ include KeyBundle
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+
2
+
3
+ module Ccrypto
4
+ class PrivateKey
5
+ attr_accessor :native_privKey
6
+ def initialize(privKey)
7
+ @native_privKey = privKey
8
+ end
9
+
10
+ def method_missing(mtd, *args, &block)
11
+ if @native_privKey.nil?
12
+ super
13
+ else
14
+ @native_privKey.send(mtd, *args, &block)
15
+ end
16
+ end
17
+
18
+ def respond_to_missing?(mtd, *args, &block)
19
+ if @native_privKey.nil?
20
+ false
21
+ else
22
+ @native_privKey.respond_to?(mtd)
23
+ end
24
+ end
25
+
26
+ end # PrivateKey
27
+
28
+ class ECCPrivateKey < PrivateKey; end
29
+ class RSAPrivateKey < PrivateKey; end
30
+ end
@@ -0,0 +1,93 @@
1
+
2
+ require 'singleton'
3
+
4
+ module Ccrypto
5
+
6
+ class ProviderException < StandardError; end
7
+
8
+ class Provider
9
+ include Singleton
10
+ include TR::CondUtils
11
+
12
+ def register(prov)
13
+ raise ProviderException, "Provider cannot be nil" if prov.nil?
14
+ raise ProviderException, "Provider must have name" if not prov.respond_to?(:provider_name)
15
+
16
+ add_provider(prov)
17
+ end
18
+
19
+ def default_provider=(prov)
20
+ raise ProviderException, "Nil provider is not supported" if prov.nil?
21
+
22
+ case prov
23
+ when String
24
+ if is_provider_registered?(prov)
25
+ @defaultProvider = find_provider(prov)
26
+ else
27
+ raise ProviderException, "Given provider '#{prov}' to set as default has yet to be registered."
28
+ end
29
+ else
30
+ if prov.respond_to?(:provider_name)
31
+ add_provider(prov) if not is_provider_registered?(prov.provider_name)
32
+ @defaultProvider = prov
33
+ else
34
+ raise ProviderException, "Given provider to set as default does not have name"
35
+ end
36
+ end
37
+
38
+ @defaultProvider
39
+ end
40
+ def default_provider
41
+ @defaultProvider
42
+ end
43
+
44
+
45
+ def find_provider(prov)
46
+ if not_empty?(prov)
47
+ providers[prov]
48
+ else
49
+ raise ProviderException, "Cannot find nil empty provider"
50
+ end
51
+ end
52
+
53
+ def provider
54
+ raise ProviderException, "No provider is registered" if is_providers_empty?
55
+
56
+ if is_empty?(default_provider)
57
+ providers.values.first
58
+ else
59
+ default_provider
60
+ end
61
+ end
62
+
63
+
64
+ private
65
+ def add_provider(prov)
66
+ providers[prov.provider_name] = prov
67
+ logger.debug "Provider '#{prov.provider_name}' registered"
68
+ end
69
+
70
+ def is_provider_registered?(provName)
71
+ providers.keys.include?(provName)
72
+ end
73
+
74
+ def is_providers_empty?
75
+ providers.empty?
76
+ end
77
+
78
+ def providers
79
+ if @providers.nil?
80
+ @providers = {}
81
+ end
82
+ @providers
83
+ end
84
+
85
+ def logger
86
+ if @logger.nil?
87
+ @logger = Tlogger.new
88
+ end
89
+ @logger
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,30 @@
1
+
2
+
3
+ module Ccrypto
4
+ class PublicKey
5
+ attr_accessor :native_pubKey
6
+ def initialize(pubkey)
7
+ @native_pubKey = pubkey
8
+ end
9
+
10
+ def method_missing(mtd, *args, &block)
11
+ if @native_pubKey.nil?
12
+ super
13
+ else
14
+ @native_pubKey.send(mtd, *args, &block)
15
+ end
16
+ end
17
+
18
+ def respond_to_missing?(mtd, *args, &block)
19
+ if @native_pubKey.nil?
20
+ false
21
+ else
22
+ @native_pubKey.respond_to?(mtd)
23
+ end
24
+ end
25
+
26
+ end # PublicKey
27
+
28
+ class ECCPublicKey < PublicKey; end
29
+ class RSAPublicKey < PublicKey; end
30
+ end
@@ -0,0 +1,13 @@
1
+
2
+
3
+ module Ccrypto
4
+ class SecretKey
5
+ attr_accessor :algo
6
+ attr_accessor :key
7
+
8
+ def initialize(algo, key)
9
+ @algo = algo
10
+ @key = key
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+
2
+
3
+ module Ccrypto
4
+ class UtilFactory
5
+ def self.instance(*args, &block)
6
+ Provider.instance.provider.util_instance(*args, &block)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ccrypto
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,12 @@
1
+
2
+
3
+ module Ccrypto
4
+ class X509Cert
5
+ attr_accessor :nativeX509
6
+
7
+ def initialize(x509)
8
+ @nativeX509 = x509
9
+ end
10
+
11
+ end
12
+ end
data/lib/ccrypto.rb ADDED
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'toolrack'
4
+ require 'tlogger'
5
+
6
+ require_relative "ccrypto/version"
7
+
8
+ require_relative 'ccrypto/provider'
9
+ require_relative 'ccrypto/algo_factory'
10
+ require_relative 'ccrypto/key_bundle'
11
+
12
+ require_relative 'ccrypto/asn1'
13
+ require_relative 'ccrypto/asn1_object'
14
+
15
+ require_relative 'ccrypto/util_factory'
16
+
17
+ Dir.glob(File.join(File.dirname(__FILE__),"ccrypto","configs","*.rb")) do |f|
18
+ require f
19
+ end
20
+
21
+ require_relative 'ccrypto/public_key'
22
+ require_relative 'ccrypto/private_key'
23
+ require_relative 'ccrypto/secret_key'
24
+
25
+ require_relative 'ccrypto/x509_cert'
26
+
27
+ module Ccrypto
28
+ class Error < StandardError; end
29
+ class CcryptoProviderException < StandardError; end
30
+
31
+ class DigestEngineException < StandardError; end
32
+ class KDFEngineException < StandardError; end
33
+ class HMACEngineException < StandardError; end
34
+ class KeypairEngineException < StandardError; end
35
+ class KeyBundleException < StandardError; end
36
+ class X509EngineException < StandardError; end
37
+ class CipherEngineException < StandardError; end
38
+ class ASN1EngineException < StandardError; end
39
+
40
+ class CompressionError < StandardError; end
41
+ class DecompressionException < StandardError; end
42
+
43
+ class MemoryBufferException < StandardError; end
44
+
45
+ class SecretSharingException < StandardError; end
46
+
47
+ class X509CertException < StandardError; end
48
+ class X509CertNotBeforeException < StandardError; end
49
+ class X509CertNotAfterException < StandardError; end
50
+
51
+ class KeyBundleStorageException < StandardError; end
52
+ # Your code goes here...
53
+ end