krypt 0.0.1
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.
- 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
|
+
|