krypt 0.0.1 → 0.0.2.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|