krypt 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.md +82 -0
- data/lib/krypt.rb +49 -0
- data/lib/krypt/asn1.rb +3 -0
- data/lib/krypt/asn1/common.rb +96 -0
- data/lib/krypt/asn1/template.rb +257 -0
- data/lib/krypt/codec.rb +57 -0
- data/lib/krypt/codec/base64.rb +140 -0
- data/lib/krypt/codec/base_codec.rb +36 -0
- data/lib/krypt/codec/hex.rb +122 -0
- data/lib/krypt/digest.rb +112 -0
- data/lib/krypt/hmac.rb +69 -0
- data/lib/krypt/pkcs5.rb +1 -0
- data/lib/krypt/pkcs5/pbkdf2.rb +41 -0
- data/lib/krypt/provider.rb +35 -0
- data/lib/krypt/x509.rb +3 -0
- data/lib/krypt/x509/certificate.rb +36 -0
- data/lib/krypt/x509/common.rb +41 -0
- data/lib/krypt/x509/crl.rb +33 -0
- data/lib/krypt_missing.rb +32 -0
- data/spec/krypt-core/MEMO.txt +85 -0
- data/spec/krypt-core/asn1/asn1_bit_string_spec.rb +475 -0
- data/spec/krypt-core/asn1/asn1_boolean_spec.rb +392 -0
- data/spec/krypt-core/asn1/asn1_constants_spec.rb +71 -0
- data/spec/krypt-core/asn1/asn1_data_spec.rb +1153 -0
- data/spec/krypt-core/asn1/asn1_end_of_contents_spec.rb +133 -0
- data/spec/krypt-core/asn1/asn1_enumerated_spec.rb +458 -0
- data/spec/krypt-core/asn1/asn1_generalized_time_spec.rb +492 -0
- data/spec/krypt-core/asn1/asn1_integer_spec.rb +557 -0
- data/spec/krypt-core/asn1/asn1_null_spec.rb +360 -0
- data/spec/krypt-core/asn1/asn1_object_id_spec.rb +495 -0
- data/spec/krypt-core/asn1/asn1_octet_string_spec.rb +456 -0
- data/spec/krypt-core/asn1/asn1_parser_spec.rb +503 -0
- data/spec/krypt-core/asn1/asn1_pem_spec.rb +282 -0
- data/spec/krypt-core/asn1/asn1_sequence_spec.rb +637 -0
- data/spec/krypt-core/asn1/asn1_set_spec.rb +795 -0
- data/spec/krypt-core/asn1/asn1_utc_time_spec.rb +495 -0
- data/spec/krypt-core/asn1/asn1_utf8_string_spec.rb +404 -0
- data/spec/krypt-core/asn1/resources.rb +53 -0
- data/spec/krypt-core/base64/base64_spec.rb +97 -0
- data/spec/krypt-core/digest/digest_spec.rb +707 -0
- data/spec/krypt-core/hex/hex_spec.rb +102 -0
- data/spec/krypt-core/pem/pem_decode_spec.rb +235 -0
- data/spec/krypt-core/resources.rb +1 -0
- data/spec/krypt-core/template/template_choice_parse_spec.rb +289 -0
- data/spec/krypt-core/template/template_dsl_spec.rb +351 -0
- data/spec/krypt-core/template/template_seq_of_parse_spec.rb +64 -0
- data/spec/krypt-core/template/template_seq_parse_spec.rb +1241 -0
- data/spec/krypt/codec/base64_decoder_spec.rb +94 -0
- data/spec/krypt/codec/base64_encoder_spec.rb +94 -0
- data/spec/krypt/codec/base64_mixed_spec.rb +16 -0
- data/spec/krypt/codec/hex_decoder_spec.rb +94 -0
- data/spec/krypt/codec/hex_encoder_spec.rb +94 -0
- data/spec/krypt/codec/hex_mixed_spec.rb +17 -0
- data/spec/krypt/codec/identity_shared.rb +119 -0
- data/spec/krypt/hmac/hmac_spec.rb +311 -0
- data/spec/krypt/pkcs5/pbkdf2_spec.rb +79 -0
- data/spec/krypt/provider/provider_spec.rb +83 -0
- data/spec/res/ca-bundle.crt +11758 -0
- data/spec/res/certificate.cer +0 -0
- data/spec/res/certificate.pem +20 -0
- data/spec/res/multiple_certs.pem +60 -0
- data/spec/resources.rb +66 -0
- data/test/helper.rb +8 -0
- data/test/res/certificate.cer +0 -0
- data/test/resources.rb +48 -0
- data/test/scratch.rb +28 -0
- data/test/test_krypt_asn1.rb +119 -0
- data/test/test_krypt_parser.rb +331 -0
- metadata +134 -0
data/lib/krypt/codec.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Krypt
|
2
|
+
|
3
|
+
# Abstract class that represents filters that can be combined with ordinary
|
4
|
+
# IO instances, filtering the output before reading/writing to the underlying
|
5
|
+
# IO. IOFilter instances can be stacked on top of each other, forming a
|
6
|
+
# "filter chain" that "peels of" multiple layers of encoding for example.
|
7
|
+
#
|
8
|
+
# IOFilter supports a basic IO interface that responds to IO#read, IO#write
|
9
|
+
# and IO#close.
|
10
|
+
#
|
11
|
+
# When reading from the IOFilter, the data will first be read from the IO,
|
12
|
+
# processed according to the rules of the filter and only then passed on.
|
13
|
+
#
|
14
|
+
# When writing to the IOFilter, the data will first be processed by
|
15
|
+
# applying the filter and only then written to the IO instance.
|
16
|
+
#
|
17
|
+
# Closing the IOFilter with IOFilter#close guarantees (among possibly
|
18
|
+
# additional things) a call to IO#close on the underlying IO.
|
19
|
+
class IOFilter
|
20
|
+
|
21
|
+
#
|
22
|
+
# call-seq:
|
23
|
+
# IOFilter.new(io) [{ |filter| block }] -> IOFilter
|
24
|
+
#
|
25
|
+
# Constructs a new IOFilter with +io+ as its underlying IO.
|
26
|
+
# Takes an optional block which is yielded the IOFilter +filter+.
|
27
|
+
# After execution of the block, it is guaranteed that IOFilter#close
|
28
|
+
# gets called on the IOFilter.
|
29
|
+
#
|
30
|
+
def initialize(io)
|
31
|
+
@io = io
|
32
|
+
if block_given?
|
33
|
+
begin
|
34
|
+
yield self
|
35
|
+
ensure
|
36
|
+
close
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# call-seq:
|
43
|
+
# io.close -> nil
|
44
|
+
#
|
45
|
+
# Calls, among possibly additional cleanup, IO#close on the underlying
|
46
|
+
# IO.
|
47
|
+
def close
|
48
|
+
@io.close
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
require_relative 'codec/hex'
|
56
|
+
require_relative 'codec/base64'
|
57
|
+
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require_relative 'base_codec'
|
2
|
+
|
3
|
+
module Krypt::Base64
|
4
|
+
|
5
|
+
module Base64Impl #:nodoc:
|
6
|
+
include Krypt::BaseCodec
|
7
|
+
|
8
|
+
def compute_len(len, a, b)
|
9
|
+
len -= @buf.size if @buf
|
10
|
+
ret = a * len / b
|
11
|
+
remainder = ret % a
|
12
|
+
if remainder
|
13
|
+
ret += a - remainder
|
14
|
+
end
|
15
|
+
ret
|
16
|
+
end
|
17
|
+
|
18
|
+
def compute_encode_read_len(len)
|
19
|
+
compute_len(len, 3, 4)
|
20
|
+
end
|
21
|
+
|
22
|
+
def compute_decode_read_len(len)
|
23
|
+
compute_len(len, 4, 3)
|
24
|
+
end
|
25
|
+
|
26
|
+
def generic_close
|
27
|
+
if @write
|
28
|
+
@io.write(Krypt::Base64.encode(@buf)) if @buf
|
29
|
+
else
|
30
|
+
raise Krypt::Base64::Base64Error.new("Remaining bytes in buffer") if @buf
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private_constant :Base64Impl
|
36
|
+
|
37
|
+
# Base64-encodes any data written or read from it in the process.
|
38
|
+
#
|
39
|
+
# === Example: Base64-encode data and write it to a file
|
40
|
+
#
|
41
|
+
# f = File.open("b64", "wb")
|
42
|
+
# b64 = Krypt::Base64::Encoder.new(f)
|
43
|
+
# b64 << "one"
|
44
|
+
# b64 << "two"
|
45
|
+
# b64.close # => contents in file will be encoded
|
46
|
+
#
|
47
|
+
# === Example: Reading from a file and Base64-encoding the data
|
48
|
+
#
|
49
|
+
# f = File.open("document", "rb")
|
50
|
+
# b64 = Krypt::Base64::Encoder.new(f)
|
51
|
+
# b64data = b64.read # => result is encoded
|
52
|
+
# b64.close
|
53
|
+
#
|
54
|
+
class Encoder < Krypt::IOFilter
|
55
|
+
include Base64Impl
|
56
|
+
|
57
|
+
#
|
58
|
+
# call-seq:
|
59
|
+
# in.read([len=nil]) -> String or nil
|
60
|
+
#
|
61
|
+
# Reads from the underlying IO and Base64-encodes the data.
|
62
|
+
# Please see IO#read for details. Note that in-place reading into
|
63
|
+
# a buffer is not supported.
|
64
|
+
#
|
65
|
+
def read(len=nil)
|
66
|
+
read_len = len ? compute_encode_read_len(len) : nil
|
67
|
+
generic_read(len, read_len) { |data| Krypt::Base64.encode(data) }
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# call-seq:
|
72
|
+
# out.write(string) -> Integer
|
73
|
+
#
|
74
|
+
# Base64-encodes +string+ and writes it to the underlying IO.
|
75
|
+
# Please see IO#write for further details.
|
76
|
+
#
|
77
|
+
def write(data)
|
78
|
+
generic_write(data, 3) { |data| Krypt::Base64.encode(data) }
|
79
|
+
end
|
80
|
+
alias << write
|
81
|
+
|
82
|
+
def close
|
83
|
+
generic_close
|
84
|
+
super
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
# Base64-decodes any data written or read from it in the process.
|
90
|
+
#
|
91
|
+
# === Example: Reading and decoding Base64-encoded data from a file
|
92
|
+
#
|
93
|
+
# f = File.open("b64", "rb")
|
94
|
+
# b64 = Krypt::Base64::Decoder.new(f)
|
95
|
+
# plain = b64.read # => result is decoded
|
96
|
+
# b64.close
|
97
|
+
#
|
98
|
+
# === Example: Writing to a file while Base64-decoding the data
|
99
|
+
#
|
100
|
+
# f = File.open("document", "wb")
|
101
|
+
# b64 = Krypt::Base64::Decoder.new(f)
|
102
|
+
# b64data = ... #some Base64-encoded data
|
103
|
+
# b64 << b64data
|
104
|
+
# b64.close # => contents in file will be decoded
|
105
|
+
#
|
106
|
+
class Decoder < Krypt::IOFilter
|
107
|
+
include Base64Impl
|
108
|
+
|
109
|
+
#
|
110
|
+
# call-seq:
|
111
|
+
# in.read([len=nil]) -> String or nil
|
112
|
+
#
|
113
|
+
# Reads from the underlying IO and Base64-decodes the data.
|
114
|
+
# Please see IO#read for further details. Note that in-place reading into
|
115
|
+
# a buffer is not supported.
|
116
|
+
#
|
117
|
+
def read(len=nil)
|
118
|
+
read_len = len ? compute_decode_read_len(len) : nil
|
119
|
+
generic_read(len, read_len) { |data| Krypt::Base64.decode(data) }
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
# call-seq:
|
124
|
+
# out.write(string) -> Integer
|
125
|
+
#
|
126
|
+
# Base64-decodes string and writes it to the underlying IO.
|
127
|
+
# Please see IO#write for further details.
|
128
|
+
#
|
129
|
+
def write(data)
|
130
|
+
generic_write(data, 4) { |data| Krypt::Base64.decode(data) }
|
131
|
+
end
|
132
|
+
alias << write
|
133
|
+
|
134
|
+
def close
|
135
|
+
generic_close
|
136
|
+
super
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Krypt::BaseCodec #:nodoc:
|
2
|
+
|
3
|
+
def generic_read(len, read_len)
|
4
|
+
data = @io.read(read_len)
|
5
|
+
data = yield data if data
|
6
|
+
if @buf
|
7
|
+
data = data || ""
|
8
|
+
data = @buf << data
|
9
|
+
end
|
10
|
+
return data unless len && data
|
11
|
+
dlen = data.size
|
12
|
+
remainder = dlen - len
|
13
|
+
update_buffer(data, dlen, remainder)
|
14
|
+
data
|
15
|
+
end
|
16
|
+
|
17
|
+
def generic_write(data, blk_size)
|
18
|
+
return 0 unless data
|
19
|
+
@write = true
|
20
|
+
data = @buf ? @buf << data : data.dup
|
21
|
+
dlen = data.size
|
22
|
+
remainder = dlen % blk_size
|
23
|
+
update_buffer(data, dlen, remainder)
|
24
|
+
@io.write(yield data) if data.size > 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def update_buffer(data, dlen, remainder)
|
28
|
+
if remainder > 0
|
29
|
+
@buf = data.slice!(dlen - remainder, remainder)
|
30
|
+
else
|
31
|
+
@buf = nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require_relative 'base_codec'
|
2
|
+
|
3
|
+
module Krypt::Hex
|
4
|
+
|
5
|
+
module HexImpl #:nodoc:
|
6
|
+
include Krypt::BaseCodec
|
7
|
+
|
8
|
+
def compute_encode_read_len(len)
|
9
|
+
len
|
10
|
+
end
|
11
|
+
|
12
|
+
def compute_decode_read_len(len)
|
13
|
+
len * 2
|
14
|
+
end
|
15
|
+
|
16
|
+
def generic_close
|
17
|
+
raise Krypt::Hex::HexError.new("Remaining bytes in buffer") if @buf
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private_constant :HexImpl
|
22
|
+
|
23
|
+
|
24
|
+
# Hex-encodes any data written or read from it in the process.
|
25
|
+
#
|
26
|
+
# === Example: Hex-encode data and write it to a file
|
27
|
+
#
|
28
|
+
# f = File.open("hex", "wb")
|
29
|
+
# hex = Krypt::Hex::Encoder.new(f)
|
30
|
+
# hex << "one"
|
31
|
+
# hex << "two"
|
32
|
+
# hex.close # => contents in file will be encoded
|
33
|
+
#
|
34
|
+
# === Example: Reading from a file and hex-encoding the data
|
35
|
+
#
|
36
|
+
# f = File.open("document", "rb")
|
37
|
+
# hex = Krypt::Hex::Encoder.new(f)
|
38
|
+
# hexdata = hex.read # => result is encoded
|
39
|
+
# hex.close
|
40
|
+
#
|
41
|
+
class Encoder < Krypt::IOFilter
|
42
|
+
include HexImpl
|
43
|
+
|
44
|
+
#
|
45
|
+
# call-seq:
|
46
|
+
# in.read([len=nil]) -> String or nil
|
47
|
+
#
|
48
|
+
# Reads from the underlying IO and hex-encodes the data.
|
49
|
+
# Please see IO#read for details. Note that in-place reading into
|
50
|
+
# a buffer is not supported.
|
51
|
+
#
|
52
|
+
def read(len=nil)
|
53
|
+
read_len = len ? compute_encode_read_len(len) : nil
|
54
|
+
generic_read(len, read_len) { |data| Krypt::Hex.encode(data) }
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# call-seq:
|
59
|
+
# out.write(string) -> Integer
|
60
|
+
#
|
61
|
+
# Hex-encodes +string+ and writes it to the underlying IO.
|
62
|
+
# Please see IO#write for further details.
|
63
|
+
#
|
64
|
+
def write(data)
|
65
|
+
generic_write(data, 1) { |data| Krypt::Hex.encode(data) }
|
66
|
+
end
|
67
|
+
alias << write
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
# Hex-decodes any data written or read from it in the process.
|
72
|
+
#
|
73
|
+
# === Example: Reading and decoding hex-encoded data from a file
|
74
|
+
#
|
75
|
+
# f = File.open("hex", "rb")
|
76
|
+
# hex = Krypt::Hex::Decoder.new(f)
|
77
|
+
# plain = hex.read # => result is decoded
|
78
|
+
# hex.close
|
79
|
+
#
|
80
|
+
# === Example: Writing to a file while hex-decoding the data
|
81
|
+
#
|
82
|
+
# f = File.open("document", "wb")
|
83
|
+
# hex = Krypt::Hex::Decoder.new(f)
|
84
|
+
# hexdata = ... #some hex-encoded data
|
85
|
+
# hex << hexdata
|
86
|
+
# hex.close # => contents in file will be decoded
|
87
|
+
#
|
88
|
+
class Decoder < Krypt::IOFilter
|
89
|
+
include HexImpl
|
90
|
+
|
91
|
+
#
|
92
|
+
# call-seq:
|
93
|
+
# in.read([len=nil], [buf=nil]) -> String or nil
|
94
|
+
#
|
95
|
+
# Reads from the underlying IO and hex-decodes the data.
|
96
|
+
# Please see IO#read for further details. Note that in-place reading into
|
97
|
+
# a buffer is not supported.
|
98
|
+
#
|
99
|
+
def read(len=nil)
|
100
|
+
read_len = len ? compute_decode_read_len(len) : nil
|
101
|
+
generic_read(len, read_len) { |data| Krypt::Hex.decode(data) }
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# call-seq:
|
106
|
+
# out.write(string) -> Integer
|
107
|
+
#
|
108
|
+
# Hex-decodes string and writes it to the underlying IO.
|
109
|
+
# Please see IO#write for further details.
|
110
|
+
#
|
111
|
+
def write(data)
|
112
|
+
generic_write(data, 2) { |data| Krypt::Hex.decode(data) }
|
113
|
+
end
|
114
|
+
alias << write
|
115
|
+
|
116
|
+
def close
|
117
|
+
generic_close
|
118
|
+
super
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
data/lib/krypt/digest.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
##
|
2
|
+
# Digest allows you to compute message digests (sometimes
|
3
|
+
# interchangeably called "hashes") of arbitrary data that are
|
4
|
+
# cryptographically secure, i.e. a Digest implements a secure one-way
|
5
|
+
# function.
|
6
|
+
#
|
7
|
+
# One-way functions offer some useful properties. E.g. given two
|
8
|
+
# distinct inputs the probability that both yield the same output
|
9
|
+
# is highly unlikely. Combined with the fact that every message digest
|
10
|
+
# algorithm has a fixed-length output of just a few bytes, digests are
|
11
|
+
# often used to create unique identifiers for arbitrary data. A common
|
12
|
+
# example is the creation of a unique id for binary documents that are
|
13
|
+
# stored in a database.
|
14
|
+
#
|
15
|
+
# Another useful characteristic of one-way functions (and thus the name)
|
16
|
+
# is that given a digest there is no indication about the original
|
17
|
+
# data that produced it, i.e. the only way to identify the original input
|
18
|
+
# is to "brute-force" through every possible combination of inputs.
|
19
|
+
#
|
20
|
+
# These characteristics make one-way functions also ideal companions
|
21
|
+
# for public key signature algorithms: instead of signing an entire
|
22
|
+
# document, first a hash of the document is produced with a considerably
|
23
|
+
# faster message digest algorithm and only the few bytes of its output
|
24
|
+
# need to be signed using the slower public key algorithm. To validate
|
25
|
+
# the integrity of a signed document, it suffices to re-compute the hash
|
26
|
+
# and verify that it is equal to that in the signature.
|
27
|
+
#
|
28
|
+
# Among the supported message digest algorithms are:
|
29
|
+
# * SHA1, SHA224, SHA256, SHA384 and SHA512
|
30
|
+
# * MD5
|
31
|
+
# * RIPEMD160
|
32
|
+
#
|
33
|
+
# For each of these algorithms, there is a convenient way to create
|
34
|
+
# instances of Digest using them, for example
|
35
|
+
#
|
36
|
+
# digest = Krypt::Digest::SHA1.new
|
37
|
+
#
|
38
|
+
# === Creating Digest by name or by Object Identifier
|
39
|
+
#
|
40
|
+
# Each supported digest algorithm has an Object Identifier (OID) associated
|
41
|
+
# with it. A Digest can either be created by passing the string
|
42
|
+
# representation of the corresponding object identifier or by a string
|
43
|
+
# representation of the algorithm name.
|
44
|
+
#
|
45
|
+
# For example, the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26, so it can
|
46
|
+
# be instantiated like this:
|
47
|
+
#
|
48
|
+
# d = Krypt::Digest.new("1.3.14.3.2.26")
|
49
|
+
# d = Krypt::Digest.new("SHA1")
|
50
|
+
# d = Krypt::Digest.new("sha1")
|
51
|
+
#
|
52
|
+
# Algorithm names may either be all upper- or all lowercase, hyphens are
|
53
|
+
# generally stripped: for instance SHA-1 becomes "SHA1", RIPEMD-160
|
54
|
+
# becomes "RIPEMD160".
|
55
|
+
#
|
56
|
+
# "Breaking" a message digest algorithm means defying its one-way
|
57
|
+
# function characteristics, i.e. producing a collision or finding a way
|
58
|
+
# to get to the original data by means that are more efficient than
|
59
|
+
# brute-forcing etc. Older digest algorithms can be considered broken
|
60
|
+
# in this sense, even the very popular MD5 and SHA1 algorithms. Should
|
61
|
+
# security be your highest concern, then you should probably rely on
|
62
|
+
# SHA224, SHA256, SHA384 or SHA512.
|
63
|
+
#
|
64
|
+
# === Hashing a file
|
65
|
+
#
|
66
|
+
# data = File.read('document')
|
67
|
+
# sha256 = Krypt::Digest::SHA256.new
|
68
|
+
# digest = sha256.digest(data)
|
69
|
+
#
|
70
|
+
# === Hashing several pieces of data at once
|
71
|
+
#
|
72
|
+
# data1 = File.read('file1')
|
73
|
+
# data2 = File.read('file2')
|
74
|
+
# data3 = File.read('file3')
|
75
|
+
# sha256 = Krypt::Digest::SHA256.new
|
76
|
+
# sha256 << data1
|
77
|
+
# sha256 << data2
|
78
|
+
# sha256 << data3
|
79
|
+
# digest = sha256.digest
|
80
|
+
#
|
81
|
+
# === Reuse a Digest instance
|
82
|
+
#
|
83
|
+
# data1 = File.read('file1')
|
84
|
+
# sha256 = Krypt::Digest::SHA256.new
|
85
|
+
# digest1 = sha256.digest(data1)
|
86
|
+
#
|
87
|
+
# data2 = File.read('file2')
|
88
|
+
# sha256.reset
|
89
|
+
# digest2 = sha256.digest(data2)
|
90
|
+
#
|
91
|
+
module Krypt::Digest
|
92
|
+
|
93
|
+
##
|
94
|
+
# Raised whenever a problem with digests occurs.
|
95
|
+
#
|
96
|
+
class DigestError < Krypt::Error; end
|
97
|
+
|
98
|
+
def self.new(name_or_oid, provider=nil)
|
99
|
+
receiver = provider ? provider : Krypt::Provider
|
100
|
+
f = ->(_) { new_service(Krypt::Digest, name_or_oid) }
|
101
|
+
receiver.instance_eval(&f)
|
102
|
+
end
|
103
|
+
|
104
|
+
%w(SHA1 SHA224 SHA256 SHA384 SHA512 RIPEMD160 MD5).each do |alg|
|
105
|
+
mod = Module.new do
|
106
|
+
define_singleton_method(:new) { Krypt::Digest.new(alg) }
|
107
|
+
end
|
108
|
+
const_set(alg, mod)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|