krypt 0.0.1 → 0.0.2.rc1
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 +7 -0
- data/lib/krypt.rb +3 -3
- data/lib/krypt/hmac.rb +0 -1
- data/lib/krypt/ossl.rb +40 -0
- data/lib/krypt/ossl/pkcs5.rb +17 -0
- data/lib/krypt/provider.rb +2 -35
- data/lib/krypt/provider/ffi.rb +6 -0
- data/lib/krypt/provider/ffi/digest.rb +226 -0
- data/lib/krypt/provider/ffi/ffi_helper.rb +13 -0
- data/lib/krypt/provider/ffi/provider.rb +72 -0
- data/lib/krypt/provider/ffi/provider_api.rb +54 -0
- data/lib/krypt/provider/provider.rb +37 -0
- data/lib/krypt/version.rb +3 -0
- data/spec/krypt-core/asn1/asn1_parser_spec.rb +3 -3
- data/spec/krypt/codec/base64_decoder_spec.rb +1 -1
- data/spec/krypt/codec/base64_encoder_spec.rb +1 -1
- data/spec/krypt/codec/hex_decoder_spec.rb +1 -1
- data/spec/krypt/codec/hex_encoder_spec.rb +1 -1
- data/spec/krypt/provider/provider_spec.rb +25 -11
- data/test/test_krypt_asn1.rb +2 -2
- data/test/test_krypt_parser.rb +1 -13
- metadata +81 -62
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 30b370a608db6282de81d662b2db509b063ddc88
|
4
|
+
data.tar.gz: 37443d86f9ef7fbaf1458d35f9d8df69de258d62
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c84ae1f12244e091658b5e4edcf502cf31c75c3126f3f982d5569c52d79f8f333c2e8a69fe606e6dc99d6c7f5095377607ce7c6f021418183e852ecf20875f14
|
7
|
+
data.tar.gz: 82e764512b1871163de9d4888b0f3e40415666555465752ff698888ccc2eb208e60e15ae2964329e7d1ed2830ebf20611e5ed0620db3c4eacb3e99bd62633d47
|
data/lib/krypt.rb
CHANGED
@@ -37,13 +37,13 @@ end
|
|
37
37
|
require_relative 'krypt_missing'
|
38
38
|
require_relative 'krypt/provider'
|
39
39
|
require_relative 'krypt/digest'
|
40
|
-
require_relative 'krypt/hmac'
|
41
|
-
require_relative 'krypt/pkcs5'
|
42
40
|
|
43
|
-
require 'krypt
|
41
|
+
require 'krypt/core'
|
44
42
|
|
45
43
|
# The following files depend on krypt-core being loaded
|
46
44
|
require_relative 'krypt/asn1'
|
47
45
|
require_relative 'krypt/x509'
|
48
46
|
require_relative 'krypt/codec'
|
47
|
+
require_relative 'krypt/pkcs5'
|
48
|
+
require_relative 'krypt/hmac'
|
49
49
|
|
data/lib/krypt/hmac.rb
CHANGED
data/lib/krypt/ossl.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= Info
|
4
|
+
|
5
|
+
krypt-ossl - A krypt shim to offer the same API as the Ruby OpenSSL extension
|
6
|
+
|
7
|
+
Copyright (C) 2013
|
8
|
+
Martin Bosslet <martin.bosslet@gmail.com>
|
9
|
+
All rights reserved.
|
10
|
+
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
12
|
+
a copy of this software and associated documentation files (the
|
13
|
+
"Software"), to deal in the Software without restriction, including
|
14
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
15
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
16
|
+
permit persons to whom the Software is furnished to do so, subject to
|
17
|
+
the following conditions:
|
18
|
+
|
19
|
+
The above copyright notice and this permission notice shall be
|
20
|
+
included in all copies or substantial portions of the Software.
|
21
|
+
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
23
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
24
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
25
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
26
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
27
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
28
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
29
|
+
|
30
|
+
=end
|
31
|
+
|
32
|
+
if RUBY_VERSION.to_f >= 1.9
|
33
|
+
require 'krypt'
|
34
|
+
|
35
|
+
module OpenSSL
|
36
|
+
class Error < StandardError; end
|
37
|
+
end unless defined? OpenSSL
|
38
|
+
|
39
|
+
require_relative 'ossl/pkcs5'
|
40
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module OpenSSL
|
2
|
+
|
3
|
+
#
|
4
|
+
# Offers the same functionality as OpenSSL::PKCS5
|
5
|
+
#
|
6
|
+
module PKCS5
|
7
|
+
module_function
|
8
|
+
|
9
|
+
def pbkdf2_hmac_sha1(pass, salt, iter, keylen)
|
10
|
+
Krypt::PBKDF2.new(Krypt::Digest::SHA1.new).generate(pass, salt, iter, keylen)
|
11
|
+
end
|
12
|
+
|
13
|
+
def pbkdf2_hmac(pass, salt, iter, keylen, digest)
|
14
|
+
Krypt::PBKDF2.new(digest).generate(pass, salt, iter, keylen)
|
15
|
+
end
|
16
|
+
end unless defined? OpenSSL::PKCS5
|
17
|
+
end
|
data/lib/krypt/provider.rb
CHANGED
@@ -1,35 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
PROVIDERS = {}
|
4
|
-
PROVIDER_LIST = []
|
5
|
-
|
6
|
-
class AlreadyExistsError < Krypt::Error; end
|
7
|
-
|
8
|
-
class ServiceNotAvailableError < Krypt::Error; end
|
9
|
-
|
10
|
-
module_function
|
11
|
-
|
12
|
-
def register(name, provider)
|
13
|
-
raise AlreadyExistsError.new("There already is a Provider named #{name}") if PROVIDERS.has_key?(name)
|
14
|
-
PROVIDERS[name] = provider
|
15
|
-
PROVIDER_LIST << name
|
16
|
-
end
|
17
|
-
|
18
|
-
def by_name(name)
|
19
|
-
PROVIDERS[name]
|
20
|
-
end
|
21
|
-
|
22
|
-
def remove(name)
|
23
|
-
PROVIDERS.delete(name)
|
24
|
-
PROVIDER_LIST.delete(name)
|
25
|
-
end
|
26
|
-
|
27
|
-
def new_service(klass, *args)
|
28
|
-
PROVIDER_LIST.reverse.each do |name|
|
29
|
-
service = PROVIDERS[name].new_service(klass, *args)
|
30
|
-
return service if service
|
31
|
-
end
|
32
|
-
raise ServiceNotAvailableError.new("The requested service is not available")
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
1
|
+
require_relative 'provider/provider'
|
2
|
+
require_relative 'provider/ffi'
|
@@ -0,0 +1,226 @@
|
|
1
|
+
module Krypt::FFI
|
2
|
+
|
3
|
+
##
|
4
|
+
# A Krypt::Digest implementation using FFI.
|
5
|
+
#
|
6
|
+
class Digest
|
7
|
+
include Krypt::FFI::LibC
|
8
|
+
|
9
|
+
##
|
10
|
+
# call-seq:
|
11
|
+
# Krypt::FFI::Digest.new(provider, name_or_oid) -> Digest
|
12
|
+
#
|
13
|
+
# Creates a Digest using a C struct krypt_provider as +provider+
|
14
|
+
# argument. The +provider+ is typically obtained by a separate FFI
|
15
|
+
# call to a publicly visible function offered by the implementation
|
16
|
+
# of the krypt Provider C API. +name_or_oid+ can be either the name
|
17
|
+
# of the digest algorithm to be used (e.g. "SHA1") or the OID String
|
18
|
+
# uniquely identifying the digest algorithm.
|
19
|
+
#
|
20
|
+
def initialize(provider, type)
|
21
|
+
unless (@handle = interface_for_name(provider, type))
|
22
|
+
unless (@handle = interface_for_oid(provider, type))
|
23
|
+
raise Krypt::Provider::ServiceNotAvailableError.new("Unknown digest algorithm: #{type}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# call-seq:
|
30
|
+
# digest.reset -> self
|
31
|
+
#
|
32
|
+
# Resets the Digest in the sense that any Digest#update that has been
|
33
|
+
# performed is abandoned and the Digest is set to its initial state again.
|
34
|
+
#
|
35
|
+
def reset
|
36
|
+
result = @handle.interface[:md_reset].call(@handle.container)
|
37
|
+
raise_on_error("Error while resetting digest", result)
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# call-seq:
|
43
|
+
# digest.update(string) -> aString
|
44
|
+
#
|
45
|
+
# Not every message digest can be computed in one single pass. If a message
|
46
|
+
# digest is to be computed from several subsequent sources, then each may
|
47
|
+
# be passed individually to the Digest instance.
|
48
|
+
#
|
49
|
+
# === Example
|
50
|
+
#
|
51
|
+
# digest = Krypt::Digest::SHA256.new
|
52
|
+
# digest.update('First input')
|
53
|
+
# digest << 'Second input' # equivalent to digest.update('Second input')
|
54
|
+
# result = digest.digest
|
55
|
+
#
|
56
|
+
def update(data)
|
57
|
+
result = @handle.interface[:md_update].call(@handle.container, data, data.length)
|
58
|
+
raise_on_error("Error while updating digest", result)
|
59
|
+
self
|
60
|
+
end
|
61
|
+
alias << update
|
62
|
+
|
63
|
+
##
|
64
|
+
# call-seq:
|
65
|
+
# digest.digest([string]) -> String
|
66
|
+
#
|
67
|
+
# When called with no arguments, the result will be the hash of the data that
|
68
|
+
# has been fed to this Digest instance so far. If called with a String
|
69
|
+
# argument, the hash of that argument will be computed.
|
70
|
+
#
|
71
|
+
# === Example
|
72
|
+
#
|
73
|
+
# digest = Krypt::Digest::SHA256.new
|
74
|
+
# result = digest.digest('First input')
|
75
|
+
#
|
76
|
+
# is equivalent to
|
77
|
+
#
|
78
|
+
# digest = Krypt::Digest::SHA256.new
|
79
|
+
# digest << 'First input' # equivalent to digest.update('Second input')
|
80
|
+
# result = digest.digest
|
81
|
+
#
|
82
|
+
def digest(data=nil)
|
83
|
+
if data
|
84
|
+
ret = digest_once(data)
|
85
|
+
else
|
86
|
+
ret = digest_finalize
|
87
|
+
end
|
88
|
+
reset
|
89
|
+
ret
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# call-seq:
|
94
|
+
# digest.hexdigest([string]) -> String
|
95
|
+
#
|
96
|
+
# Works the with the same semantics as Digest#digest with the difference that
|
97
|
+
# instead of the raw bytes the hex-encoded form of the raw representation is
|
98
|
+
# returned.
|
99
|
+
#
|
100
|
+
def hexdigest(data=nil)
|
101
|
+
Krypt::Hex.encode(digest(data))
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# call-seq:
|
106
|
+
# digest.digest_length -> integer
|
107
|
+
#
|
108
|
+
# Returns the output size of the digest, i.e. the length in bytes of the
|
109
|
+
# final message digest result.
|
110
|
+
#
|
111
|
+
# === Example
|
112
|
+
# digest = Krypt::Digest::SHA1.new
|
113
|
+
# puts digest.digest_length # => 20
|
114
|
+
#
|
115
|
+
def digest_length
|
116
|
+
read_length(@handle.interface[:md_digest_length])
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# call-seq:
|
121
|
+
# digest.block_length -> integer
|
122
|
+
#
|
123
|
+
# Returns the block length of the digest algorithm, i.e. the length in bytes
|
124
|
+
# of an individual block. Most modern algorithms partition a message to be
|
125
|
+
# digested into a sequence of fix-sized blocks that are processed
|
126
|
+
# consecutively.
|
127
|
+
#
|
128
|
+
# === Example
|
129
|
+
# digest = Krypt::Digest::SHA1.new
|
130
|
+
# puts digest.block_length # => 64
|
131
|
+
#
|
132
|
+
def block_length
|
133
|
+
read_length(@handle.interface[:md_block_length])
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# call-seq:
|
138
|
+
# digest.name -> string
|
139
|
+
#
|
140
|
+
# Returns the sn of this Digest instance.
|
141
|
+
#
|
142
|
+
# === Example
|
143
|
+
#
|
144
|
+
# digest = Krypt::Digest::SHA512.new
|
145
|
+
# puts digest.name # => SHA512
|
146
|
+
#
|
147
|
+
def name
|
148
|
+
name_ptr = FFI::MemoryPointer.new(:pointer)
|
149
|
+
result = @handle.interface[:md_name].call(@handle.container, name_ptr)
|
150
|
+
raise_on_error("Error while obtaining digest name", result)
|
151
|
+
|
152
|
+
name_ptr.read_pointer.get_string(0)
|
153
|
+
end
|
154
|
+
|
155
|
+
private
|
156
|
+
|
157
|
+
def raise_on_error(msg, result)
|
158
|
+
raise Krypt::Digest::DigestError.new(msg) unless result == Krypt::FFI::ProviderAPI::KRYPT_OK
|
159
|
+
end
|
160
|
+
|
161
|
+
def digest_once(data)
|
162
|
+
digest_ptr = ::FFI::MemoryPointer.new(:pointer)
|
163
|
+
size_ptr = ::FFI::MemoryPointer.new(:pointer)
|
164
|
+
result = @handle.interface[:md_digest].call(@handle.container, data, data.length, digest_ptr, size_ptr)
|
165
|
+
raise_on_error("Error while computing digest", result)
|
166
|
+
|
167
|
+
digest_ptr = digest_ptr.read_pointer
|
168
|
+
size = size_ptr.read_int
|
169
|
+
ret = digest_ptr.get_bytes(0, size)
|
170
|
+
free(digest_ptr)
|
171
|
+
ret
|
172
|
+
end
|
173
|
+
|
174
|
+
def digest_finalize
|
175
|
+
digest_ptr = ::FFI::MemoryPointer.new(:pointer)
|
176
|
+
size_ptr = ::FFI::MemoryPointer.new(:pointer)
|
177
|
+
result = @handle.interface[:md_final].call(@handle.container, digest_ptr, size_ptr)
|
178
|
+
raise_on_error("Error while computing digest", result)
|
179
|
+
|
180
|
+
digest_ptr = digest_ptr.read_pointer
|
181
|
+
size = size_ptr.read_int
|
182
|
+
ret = digest_ptr.get_bytes(0, size)
|
183
|
+
free(digest_ptr)
|
184
|
+
ret
|
185
|
+
end
|
186
|
+
|
187
|
+
def read_length(fp)
|
188
|
+
size_ptr = ::FFI::MemoryPointer.new(:pointer)
|
189
|
+
result = fp.call(@handle.container, size_ptr)
|
190
|
+
raise_on_error("Error while obtaining block length", result)
|
191
|
+
|
192
|
+
size_ptr.read_int
|
193
|
+
end
|
194
|
+
|
195
|
+
def interface_for_name(provider, name)
|
196
|
+
digest_ctor = provider[:md_new_name]
|
197
|
+
get_native_handle(provider, digest_ctor, name)
|
198
|
+
end
|
199
|
+
|
200
|
+
def interface_for_oid(provider, oid)
|
201
|
+
digest_ctor = provider[:md_new_oid]
|
202
|
+
get_native_handle(provider, digest_ctor, oid)
|
203
|
+
end
|
204
|
+
|
205
|
+
def get_native_handle(provider, digest_ctor, type)
|
206
|
+
container_ptr = digest_ctor.call(provider, type)
|
207
|
+
return nil if nil == container_ptr || container_ptr.null?
|
208
|
+
|
209
|
+
container = Krypt::FFI::ProviderAPI::KryptMd.new(container_ptr)
|
210
|
+
interface_ptr = container[:methods]
|
211
|
+
interface = Krypt::FFI::ProviderAPI::DigestInterface.new(interface_ptr)
|
212
|
+
NativeHandle.new(container, interface)
|
213
|
+
end
|
214
|
+
|
215
|
+
class NativeHandle #:nodoc:
|
216
|
+
attr_reader :container
|
217
|
+
attr_reader :interface
|
218
|
+
|
219
|
+
def initialize(container, interface)
|
220
|
+
@container = container
|
221
|
+
@interface = interface
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Krypt::FFI
|
2
|
+
|
3
|
+
module LibC
|
4
|
+
extend ::FFI::Library
|
5
|
+
|
6
|
+
ffi_lib ::FFI::Library::LIBC
|
7
|
+
|
8
|
+
attach_function :malloc, [:size_t], :pointer
|
9
|
+
attach_function :free, [:pointer], :void
|
10
|
+
attach_function :memcpy, [:pointer, :pointer, :size_t], :void
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Krypt::FFI
|
2
|
+
|
3
|
+
##
|
4
|
+
# A Krypt::Provider implementation for C-based implementations of the
|
5
|
+
# krypt Provider C API (krypt-provider.h). Provides the necessary "glue"
|
6
|
+
# to link the native implementation to the corresponding Ruby interfaces.
|
7
|
+
#
|
8
|
+
class Provider
|
9
|
+
|
10
|
+
##
|
11
|
+
# call-seq:
|
12
|
+
# Krypt::FFI::Provider.new(native_provider) -> Provider
|
13
|
+
#
|
14
|
+
# The +native_provider+ is typically obtained by a separate FFI
|
15
|
+
# call to a publicly visible function offered by the implementation
|
16
|
+
# of the krypt Provider C API.
|
17
|
+
#
|
18
|
+
def initialize(native_provider)
|
19
|
+
@provider = Krypt::FFI::ProviderAPI::ProviderInterface.new(native_provider)
|
20
|
+
@provider[:init].call(@provider, nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# call-seq:
|
25
|
+
# provider.name -> String
|
26
|
+
#
|
27
|
+
# Every Provider has a default name identifying it.
|
28
|
+
#
|
29
|
+
def name
|
30
|
+
@provider[:name]
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# call-seq:
|
35
|
+
# provider.new_service(klass, [arg1, arg2, ...]) -> service
|
36
|
+
#
|
37
|
+
# Provides access to the individual services offered by this provider.
|
38
|
+
# +klass+ is the Ruby class of the desired service (e.g. Krypt::Digest),
|
39
|
+
# followed by optional additional arguments needed to create an instance
|
40
|
+
# of the service.
|
41
|
+
#
|
42
|
+
# === Example
|
43
|
+
#
|
44
|
+
# digest = provider.new_service(Krypt::Digest, "SHA1")
|
45
|
+
#
|
46
|
+
def new_service(klass, *args)
|
47
|
+
return new_digest(*args) if klass == Krypt::Digest
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# call-seq:
|
53
|
+
# provider.finalize -> nil
|
54
|
+
#
|
55
|
+
# Depending on its implementation, it may be possible that a native krypt
|
56
|
+
# provider needs to do some cleanup before it is subject to GC. This method
|
57
|
+
# delegates to the native krypt_provider implementation of finalize. It is
|
58
|
+
# called whenever a Provider::delete is called to remove a specific
|
59
|
+
# provider.
|
60
|
+
#
|
61
|
+
def finalize
|
62
|
+
@provider[:finalize].call(@provider)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def new_digest(name_or_oid)
|
68
|
+
Krypt::FFI::Digest.new(@provider, name_or_oid)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Krypt::FFI
|
2
|
+
|
3
|
+
module ProviderAPI
|
4
|
+
extend ::FFI::Library
|
5
|
+
|
6
|
+
ffi_lib ::FFI::CURRENT_PROCESS
|
7
|
+
|
8
|
+
KRYPT_OK = 1
|
9
|
+
KRYPT_ERR = -1
|
10
|
+
|
11
|
+
callback :fp_init, [:pointer, :pointer], :void
|
12
|
+
callback :fp_finalize, [:pointer], :void
|
13
|
+
callback :fp_md_new_name, [:pointer, :string], :pointer
|
14
|
+
callback :fp_md_new_oid, [:pointer, :string], :pointer
|
15
|
+
|
16
|
+
class ProviderInterface < ::FFI::Struct
|
17
|
+
layout :name, :string,
|
18
|
+
:init, :fp_init,
|
19
|
+
:finalize, :fp_finalize,
|
20
|
+
:md_new_oid, :fp_md_new_oid,
|
21
|
+
:md_new_name, :fp_md_new_name
|
22
|
+
end
|
23
|
+
|
24
|
+
class KryptMd < ::FFI::Struct
|
25
|
+
layout :provider, :pointer,
|
26
|
+
:methods, :pointer
|
27
|
+
end
|
28
|
+
|
29
|
+
callback :fp_md_reset, [:pointer], :int
|
30
|
+
#callback :fp_md_update, [:pointer, :buffer_in, :size_t], :int
|
31
|
+
callback :fp_md_update, [:pointer, :pointer, :size_t], :int
|
32
|
+
callback :fp_md_final, [:pointer, :pointer, :pointer], :int
|
33
|
+
callback :fp_md_digest, [:pointer, :pointer, :size_t, :pointer, :pointer], :int
|
34
|
+
callback :fp_md_digest_length, [:pointer, :pointer], :int
|
35
|
+
callback :fp_md_block_length, [:pointer, :pointer], :int
|
36
|
+
callback :fp_md_name, [:pointer, :pointer], :int
|
37
|
+
callback :fp_md_mark, [:pointer], :void
|
38
|
+
callback :fp_md_free, [:pointer], :void
|
39
|
+
|
40
|
+
class DigestInterface < ::FFI::Struct
|
41
|
+
layout :md_reset, :fp_md_reset,
|
42
|
+
:md_update, :fp_md_update,
|
43
|
+
:md_final, :fp_md_final,
|
44
|
+
:md_digest, :fp_md_digest,
|
45
|
+
:md_digest_length, :fp_md_digest_length,
|
46
|
+
:md_block_length, :fp_md_block_length,
|
47
|
+
:md_name, :fp_md_name,
|
48
|
+
:md_mark, :fp_md_mark,
|
49
|
+
:md_free, :fp_md_free
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Krypt::Provider
|
2
|
+
|
3
|
+
PROVIDERS = {}
|
4
|
+
PROVIDER_LIST = []
|
5
|
+
|
6
|
+
class AlreadyExistsError < Krypt::Error; end
|
7
|
+
|
8
|
+
class ServiceNotAvailableError < Krypt::Error; end
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def register(provider, name=nil)
|
13
|
+
name ||= provider.name
|
14
|
+
raise AlreadyExistsError.new("There already is a Provider named #{name}") if PROVIDERS.has_key?(name)
|
15
|
+
PROVIDERS[name] = provider
|
16
|
+
PROVIDER_LIST.unshift(name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def by_name(name)
|
20
|
+
PROVIDERS[name]
|
21
|
+
end
|
22
|
+
|
23
|
+
def remove(name)
|
24
|
+
p = PROVIDERS.delete(name)
|
25
|
+
PROVIDER_LIST.delete(name)
|
26
|
+
p.finalize
|
27
|
+
end
|
28
|
+
|
29
|
+
def new_service(klass, *args)
|
30
|
+
PROVIDER_LIST.each do |name|
|
31
|
+
service = PROVIDERS[name].new_service(klass, *args)
|
32
|
+
return service if service
|
33
|
+
end
|
34
|
+
raise ServiceNotAvailableError.new("The requested service is not available")
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -23,9 +23,9 @@ describe Krypt::ASN1::Parser do
|
|
23
23
|
it "should be reusable for several IOs" do
|
24
24
|
parser = Krypt::ASN1::Parser.new
|
25
25
|
io = Resources.certificate_io
|
26
|
-
do_and_close(io) { |
|
26
|
+
do_and_close(io) { |nio| parser.next(nio).should_not be_nil }
|
27
27
|
io = Resources.certificate_io
|
28
|
-
do_and_close(io) { |
|
28
|
+
do_and_close(io) { |nio| parser.next(nio).should_not be_nil }
|
29
29
|
end
|
30
30
|
|
31
31
|
end
|
@@ -36,7 +36,7 @@ describe Krypt::ASN1::Parser, "#next" do
|
|
36
36
|
|
37
37
|
it "returns a Header when called on an IO representing an ASN.1" do
|
38
38
|
io = Resources.certificate_io
|
39
|
-
do_and_close(io) { |
|
39
|
+
do_and_close(io) { |nio| parse_next nio }
|
40
40
|
parse_next(StringIO.new(Resources.certificate))
|
41
41
|
end
|
42
42
|
|
@@ -11,9 +11,23 @@ describe "Krypt::Provider" do
|
|
11
11
|
let(:prov) { Krypt::Provider }
|
12
12
|
|
13
13
|
describe "#register=" do
|
14
|
+
it "takes an optional name parameter" do
|
15
|
+
-> { prov.register(:name, Object.new) }.should_not raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
it "takes the name from the provider directly if none is provided" do
|
19
|
+
p1 = Object.new
|
20
|
+
p2 = Object.new
|
21
|
+
def p2.name
|
22
|
+
"test"
|
23
|
+
end
|
24
|
+
-> { prov.register(p1) }.should raise_error NoMethodError
|
25
|
+
-> { prov.register(p2) }.should_not raise_error
|
26
|
+
end
|
27
|
+
|
14
28
|
it "does not allow to register a provider twice under the same name" do
|
15
|
-
prov.register(
|
16
|
-
-> { prov.register(
|
29
|
+
prov.register(Object.new, :name)
|
30
|
+
-> { prov.register(Object.new, :name) }.should raise_error prov::AlreadyExistsError
|
17
31
|
end
|
18
32
|
end
|
19
33
|
|
@@ -25,7 +39,7 @@ describe "Krypt::Provider" do
|
|
25
39
|
context "returns the provider that has been assigned to a given name" do
|
26
40
|
let(:instance) { Object.new }
|
27
41
|
specify do
|
28
|
-
prov.register(:name
|
42
|
+
prov.register(instance, :name)
|
29
43
|
prov.by_name(:name).should eq(instance)
|
30
44
|
end
|
31
45
|
end
|
@@ -52,28 +66,28 @@ describe "Krypt::Provider" do
|
|
52
66
|
|
53
67
|
context "returns provider features based on the order they were registered" do
|
54
68
|
it "raises ServiceNotAvailableError if a requested feature is not supported by any provider" do
|
55
|
-
prov.register(:a
|
56
|
-
prov.register(:b
|
69
|
+
prov.register(provider_a, :a)
|
70
|
+
prov.register(provider_b, :b)
|
57
71
|
-> { prov.new_service(Object, "test") }.should raise_error prov::ServiceNotAvailableError
|
58
72
|
end
|
59
73
|
|
60
74
|
it "finds a service only available in a specific provider" do
|
61
|
-
prov.register(:a
|
62
|
-
prov.register(:b
|
75
|
+
prov.register(provider_a, :a)
|
76
|
+
prov.register(provider_b, :b)
|
63
77
|
prov.new_service(String).should eq(:A)
|
64
78
|
prov.new_service(Integer).should eq(:B)
|
65
79
|
end
|
66
80
|
|
67
81
|
context "returns the service of the provider registered last if the service is supported by more than one provider" do
|
68
82
|
specify "first a, then b" do
|
69
|
-
prov.register(:a
|
70
|
-
prov.register(:b
|
83
|
+
prov.register(provider_a, :a)
|
84
|
+
prov.register(provider_b, :b)
|
71
85
|
prov.new_service(Krypt::Digest).should eq(:B)
|
72
86
|
end
|
73
87
|
|
74
88
|
specify "first b, then a" do
|
75
|
-
prov.register(:b
|
76
|
-
prov.register(:a
|
89
|
+
prov.register(provider_b, :b)
|
90
|
+
prov.register(provider_a, :a)
|
77
91
|
prov.new_service(Krypt::Digest).should eq(:A)
|
78
92
|
end
|
79
93
|
end
|
data/test/test_krypt_asn1.rb
CHANGED
@@ -94,8 +94,8 @@ class Krypt::ASN1Test < Test::Unit::TestCase
|
|
94
94
|
io = StringIO.new
|
95
95
|
cons_header.encode_to(io)
|
96
96
|
asn1 = Krypt::ASN1.decode(val)
|
97
|
-
asn1.each do |
|
98
|
-
|
97
|
+
asn1.each do |value|
|
98
|
+
value.encode_to(io)
|
99
99
|
end
|
100
100
|
assert_equal(val, io.string.force_encoding("ASCII-8BIT"))
|
101
101
|
end
|
data/test/test_krypt_parser.rb
CHANGED
@@ -73,19 +73,6 @@ class Krypt::ParserTest < Test::Unit::TestCase
|
|
73
73
|
assert_header_value_equal(raw, header)
|
74
74
|
end
|
75
75
|
|
76
|
-
def test_parse_constructed
|
77
|
-
raw = [%w{30 06 04 01 01 04 01 02}.join("")].pack("H*")
|
78
|
-
parser = Krypt::ASN1::Parser.new
|
79
|
-
io = StringIO.new(raw)
|
80
|
-
header = parser.next(io)
|
81
|
-
assert_equal(Krypt::ASN1::SEQUENCE, header.tag)
|
82
|
-
assert_equal(:UNIVERSAL, header.tag_class)
|
83
|
-
assert_equal(true, header.constructed?)
|
84
|
-
assert_equal(false, header.infinite?)
|
85
|
-
assert_equal(6, header.length)
|
86
|
-
assert_equal(2, header.header_length)
|
87
|
-
assert_header_value_equal(raw, header)
|
88
|
-
end
|
89
76
|
|
90
77
|
def test_parse_constructed
|
91
78
|
raw = [%w{30 02 80 01 00}.join("")].pack("H*")
|
@@ -297,6 +284,7 @@ class Krypt::ParserTest < Test::Unit::TestCase
|
|
297
284
|
when :AT_ONCE
|
298
285
|
result << value_io.read
|
299
286
|
when :STREAMING
|
287
|
+
buf = nil
|
300
288
|
while buf = value_io.read(3, buf)
|
301
289
|
result << buf
|
302
290
|
end
|
metadata
CHANGED
@@ -1,32 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: krypt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.2.rc1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Hiroshi Nakamura, Martin Bosslet
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-02-23 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
14
27
|
- !ruby/object:Gem::Dependency
|
15
28
|
name: krypt-core
|
16
29
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
30
|
requirements:
|
19
31
|
- - '='
|
20
32
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.0.
|
33
|
+
version: 0.0.2.rc1
|
22
34
|
type: :runtime
|
23
35
|
prerelease: false
|
24
36
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
37
|
requirements:
|
27
38
|
- - '='
|
28
39
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.0.
|
40
|
+
version: 0.0.2.rc1
|
30
41
|
description: krypt provides a unified framework for Ruby cryptography by offering
|
31
42
|
a platform- and library-independent provider mechanism.
|
32
43
|
email: Martin.Bosslet@gmail.com
|
@@ -35,100 +46,108 @@ extensions: []
|
|
35
46
|
extra_rdoc_files:
|
36
47
|
- README.md
|
37
48
|
files:
|
38
|
-
-
|
39
|
-
-
|
40
|
-
- lib/krypt
|
41
|
-
- lib/krypt/
|
49
|
+
- LICENSE
|
50
|
+
- README.md
|
51
|
+
- lib/krypt.rb
|
52
|
+
- lib/krypt/asn1.rb
|
53
|
+
- lib/krypt/asn1/common.rb
|
54
|
+
- lib/krypt/asn1/template.rb
|
55
|
+
- lib/krypt/codec.rb
|
42
56
|
- lib/krypt/codec/base64.rb
|
57
|
+
- lib/krypt/codec/base_codec.rb
|
43
58
|
- lib/krypt/codec/hex.rb
|
59
|
+
- lib/krypt/digest.rb
|
60
|
+
- lib/krypt/hmac.rb
|
61
|
+
- lib/krypt/ossl.rb
|
62
|
+
- lib/krypt/ossl/pkcs5.rb
|
63
|
+
- lib/krypt/pkcs5.rb
|
44
64
|
- lib/krypt/pkcs5/pbkdf2.rb
|
45
65
|
- lib/krypt/provider.rb
|
66
|
+
- lib/krypt/provider/ffi.rb
|
67
|
+
- lib/krypt/provider/ffi/digest.rb
|
68
|
+
- lib/krypt/provider/ffi/ffi_helper.rb
|
69
|
+
- lib/krypt/provider/ffi/provider.rb
|
70
|
+
- lib/krypt/provider/ffi/provider_api.rb
|
71
|
+
- lib/krypt/provider/provider.rb
|
72
|
+
- lib/krypt/version.rb
|
46
73
|
- lib/krypt/x509.rb
|
47
|
-
- lib/krypt/
|
48
|
-
- lib/krypt/
|
49
|
-
- lib/krypt/
|
50
|
-
- lib/krypt/pkcs5.rb
|
51
|
-
- lib/krypt/digest.rb
|
52
|
-
- lib/krypt/asn1.rb
|
53
|
-
- lib/krypt/codec.rb
|
54
|
-
- lib/krypt.rb
|
74
|
+
- lib/krypt/x509/certificate.rb
|
75
|
+
- lib/krypt/x509/common.rb
|
76
|
+
- lib/krypt/x509/crl.rb
|
55
77
|
- lib/krypt_missing.rb
|
56
|
-
- spec/krypt/codec/hex_decoder_spec.rb
|
57
|
-
- spec/krypt/codec/hex_mixed_spec.rb
|
58
|
-
- spec/krypt/codec/hex_encoder_spec.rb
|
59
|
-
- spec/krypt/codec/base64_encoder_spec.rb
|
60
|
-
- spec/krypt/codec/base64_mixed_spec.rb
|
61
|
-
- spec/krypt/codec/identity_shared.rb
|
62
|
-
- spec/krypt/codec/base64_decoder_spec.rb
|
63
|
-
- spec/krypt/pkcs5/pbkdf2_spec.rb
|
64
|
-
- spec/krypt/hmac/hmac_spec.rb
|
65
|
-
- spec/krypt/provider/provider_spec.rb
|
66
|
-
- spec/krypt-core/digest/digest_spec.rb
|
67
78
|
- spec/krypt-core/MEMO.txt
|
68
|
-
- spec/krypt-core/
|
69
|
-
- spec/krypt-core/asn1/
|
79
|
+
- spec/krypt-core/asn1/asn1_bit_string_spec.rb
|
80
|
+
- spec/krypt-core/asn1/asn1_boolean_spec.rb
|
81
|
+
- spec/krypt-core/asn1/asn1_constants_spec.rb
|
70
82
|
- spec/krypt-core/asn1/asn1_data_spec.rb
|
83
|
+
- spec/krypt-core/asn1/asn1_end_of_contents_spec.rb
|
84
|
+
- spec/krypt-core/asn1/asn1_enumerated_spec.rb
|
71
85
|
- spec/krypt-core/asn1/asn1_generalized_time_spec.rb
|
72
|
-
- spec/krypt-core/asn1/asn1_parser_spec.rb
|
73
86
|
- spec/krypt-core/asn1/asn1_integer_spec.rb
|
74
|
-
- spec/krypt-core/asn1/asn1_set_spec.rb
|
75
|
-
- spec/krypt-core/asn1/asn1_enumerated_spec.rb
|
76
|
-
- spec/krypt-core/asn1/asn1_octet_string_spec.rb
|
77
|
-
- spec/krypt-core/asn1/asn1_bit_string_spec.rb
|
78
|
-
- spec/krypt-core/asn1/asn1_constants_spec.rb
|
79
|
-
- spec/krypt-core/asn1/asn1_utc_time_spec.rb
|
80
87
|
- spec/krypt-core/asn1/asn1_null_spec.rb
|
81
|
-
- spec/krypt-core/asn1/asn1_sequence_spec.rb
|
82
|
-
- spec/krypt-core/asn1/asn1_boolean_spec.rb
|
83
88
|
- spec/krypt-core/asn1/asn1_object_id_spec.rb
|
89
|
+
- spec/krypt-core/asn1/asn1_octet_string_spec.rb
|
90
|
+
- spec/krypt-core/asn1/asn1_parser_spec.rb
|
91
|
+
- spec/krypt-core/asn1/asn1_pem_spec.rb
|
92
|
+
- spec/krypt-core/asn1/asn1_sequence_spec.rb
|
93
|
+
- spec/krypt-core/asn1/asn1_set_spec.rb
|
94
|
+
- spec/krypt-core/asn1/asn1_utc_time_spec.rb
|
84
95
|
- spec/krypt-core/asn1/asn1_utf8_string_spec.rb
|
85
96
|
- spec/krypt-core/asn1/resources.rb
|
86
|
-
- spec/krypt-core/asn1/asn1_end_of_contents_spec.rb
|
87
97
|
- spec/krypt-core/base64/base64_spec.rb
|
98
|
+
- spec/krypt-core/digest/digest_spec.rb
|
99
|
+
- spec/krypt-core/hex/hex_spec.rb
|
88
100
|
- spec/krypt-core/pem/pem_decode_spec.rb
|
101
|
+
- spec/krypt-core/resources.rb
|
89
102
|
- spec/krypt-core/template/template_choice_parse_spec.rb
|
90
|
-
- spec/krypt-core/template/template_seq_parse_spec.rb
|
91
|
-
- spec/krypt-core/template/template_seq_of_parse_spec.rb
|
92
103
|
- spec/krypt-core/template/template_dsl_spec.rb
|
93
|
-
- spec/krypt-core/
|
94
|
-
- spec/
|
95
|
-
- spec/
|
104
|
+
- spec/krypt-core/template/template_seq_of_parse_spec.rb
|
105
|
+
- spec/krypt-core/template/template_seq_parse_spec.rb
|
106
|
+
- spec/krypt/codec/base64_decoder_spec.rb
|
107
|
+
- spec/krypt/codec/base64_encoder_spec.rb
|
108
|
+
- spec/krypt/codec/base64_mixed_spec.rb
|
109
|
+
- spec/krypt/codec/hex_decoder_spec.rb
|
110
|
+
- spec/krypt/codec/hex_encoder_spec.rb
|
111
|
+
- spec/krypt/codec/hex_mixed_spec.rb
|
112
|
+
- spec/krypt/codec/identity_shared.rb
|
113
|
+
- spec/krypt/hmac/hmac_spec.rb
|
114
|
+
- spec/krypt/pkcs5/pbkdf2_spec.rb
|
115
|
+
- spec/krypt/provider/provider_spec.rb
|
96
116
|
- spec/res/ca-bundle.crt
|
97
|
-
- spec/res/multiple_certs.pem
|
98
117
|
- spec/res/certificate.cer
|
99
|
-
-
|
100
|
-
-
|
118
|
+
- spec/res/certificate.pem
|
119
|
+
- spec/res/multiple_certs.pem
|
120
|
+
- spec/resources.rb
|
101
121
|
- test/helper.rb
|
102
|
-
- test/test_krypt_asn1.rb
|
103
|
-
- test/resources.rb
|
104
122
|
- test/res/certificate.cer
|
105
|
-
-
|
106
|
-
-
|
123
|
+
- test/resources.rb
|
124
|
+
- test/scratch.rb
|
125
|
+
- test/test_krypt_asn1.rb
|
126
|
+
- test/test_krypt_parser.rb
|
107
127
|
homepage: https://github.com/krypt/krypt
|
108
128
|
licenses:
|
109
129
|
- MIT
|
130
|
+
metadata: {}
|
110
131
|
post_install_message:
|
111
132
|
rdoc_options: []
|
112
133
|
require_paths:
|
113
134
|
- lib
|
114
135
|
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
136
|
requirements:
|
117
|
-
- -
|
137
|
+
- - ">="
|
118
138
|
- !ruby/object:Gem::Version
|
119
139
|
version: 1.9.3
|
120
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
141
|
requirements:
|
123
|
-
- -
|
142
|
+
- - ">"
|
124
143
|
- !ruby/object:Gem::Version
|
125
|
-
version:
|
144
|
+
version: 1.3.1
|
126
145
|
requirements: []
|
127
146
|
rubyforge_project:
|
128
|
-
rubygems_version:
|
147
|
+
rubygems_version: 2.2.0
|
129
148
|
signing_key:
|
130
|
-
specification_version:
|
149
|
+
specification_version: 4
|
131
150
|
summary: Platform- and library-independent cryptography for Ruby
|
132
151
|
test_files:
|
133
|
-
- test/test_krypt_parser.rb
|
134
152
|
- test/test_krypt_asn1.rb
|
153
|
+
- test/test_krypt_parser.rb
|