ccrypto 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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