sodium 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/.gitignore +6 -0
- data/.travis.yml +10 -7
- data/CHANGELOG.md +20 -0
- data/Gemfile +3 -1
- data/README.md +1 -1
- data/VERSION +1 -1
- data/certs/sodium@touset.org.cert +20 -0
- data/{sodium.pub.gpg → certs/sodium@touset.org.pub.gpg} +0 -0
- data/config/nacl_ffi.yml +16 -16
- data/ext/sodium/memory/extconf.rb +11 -0
- data/ext/sodium/memory/memory.c +16 -0
- data/lib/sodium/auth.rb +21 -11
- data/lib/sodium/box.rb +6 -6
- data/lib/sodium/buffer.rb +90 -12
- data/lib/sodium/ffi.rb +1 -0
- data/lib/sodium/ffi/crypto.rb +3 -2
- data/lib/sodium/ffi/memory.rb +12 -0
- data/lib/sodium/secret_box.rb +4 -4
- data/sodium.gemspec +9 -4
- data/tasks/extensions.rake +24 -0
- data/test/sodium/auth/hmacsha256_test.rb +11 -0
- data/test/sodium/auth/hmacsha512256_test.rb +11 -0
- data/test/sodium/buffer_test.rb +88 -31
- metadata +35 -6
- metadata.gz.sig +0 -0
data.tar.gz.sig
ADDED
Binary file
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
script: bundle exec rake test
|
2
2
|
|
3
|
+
bundler_args: --without tools
|
4
|
+
|
3
5
|
env:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
6
|
+
matrix:
|
7
|
+
- >
|
8
|
+
LIBSODIUM_MIRROR="https://github.com/jedisct1/libsodium/tarball/%s"
|
9
|
+
LIBSODIUM_VERSION="master"
|
10
|
+
# - >
|
11
|
+
# LIBSODIUM_MIRROR="http://download.dnscrypt.org/libsodium/releases/libsodium-%s.tar.gz"
|
12
|
+
# LIBSODIUM_VERSION=0.4.1
|
13
|
+
# LIBSODIUM_DIGEST=65756c7832950401cc0e6ee0e99b165974244e749f40f33d465f56447bae8ce3
|
11
14
|
|
12
15
|
rvm:
|
13
16
|
- 1.8.7
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
### 0.6.0 (2013-06-27)
|
2
|
+
|
3
|
+
- Additions
|
4
|
+
* Sodium::Auth can be used entirely with class methods
|
5
|
+
* Sodium::Buffer gains many new API methods
|
6
|
+
* signed gem
|
7
|
+
|
8
|
+
- Removals
|
9
|
+
* Sodium::Buffer loses #pad, #unpad
|
10
|
+
|
11
|
+
- Enhancements
|
12
|
+
* Sodium::Buffer performance improvements
|
13
|
+
|
14
|
+
- Bug Fixes
|
15
|
+
* using `pointer` type for FFI methods to avoid bugs related to
|
16
|
+
in/out buffers in JRuby
|
17
|
+
|
18
|
+
### 0.5.0 (2013-06-05)
|
19
|
+
|
20
|
+
- Initial release
|
data/Gemfile
CHANGED
data/README.md
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
@@ -0,0 +1,20 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDMDCCAhigAwIBAgIBADANBgkqhkiG9w0BAQUFADA+MQ8wDQYDVQQDDAZzb2Rp
|
3
|
+
dW0xFjAUBgoJkiaJk/IsZAEZFgZ0b3VzZXQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
4
|
+
HhcNMTMwNjI4MDEzMzQ4WhcNMTQwNjI4MDEzMzQ4WjA+MQ8wDQYDVQQDDAZzb2Rp
|
5
|
+
dW0xFjAUBgoJkiaJk/IsZAEZFgZ0b3VzZXQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
6
|
+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCh3C2P1jW4MvcpXioNkqW/
|
7
|
+
HiD9ZpTew1tHTolQclBBmOmOApLUPc9PIsfbohph83Z82x+BWbjEdL5NAfEQjRVu
|
8
|
+
O8JUBJh0YRDF9P7fDtd9w0b3mmhumujbEsmDYs1ru5VvjgCh+Hfxgddlpha0KmxQ
|
9
|
+
0j3h/Uj27tFbE33dIRqb5dBBBnnIM5CqRMu5/gDeXN5GrjYK3JfZlzZRECjnfuR5
|
10
|
+
qDqoQFJK5ZmaEFm9E88HdAIS+sV9zb1OCYlADr3EB/a3Shxedx4SsX7oBPyNfsRb
|
11
|
+
kMdTr+VynH/OEPSo0dW1DuKpUCmNBscrTOwhn6hJUDNpr6f0CTfYG9jGJY3p5JMt
|
12
|
+
AgMBAAGjOTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFIu3aZS82t6UR4Z5eON3t2LI
|
13
|
+
AHPeMAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAkjXdsFKC9mQfT3tP
|
14
|
+
PNtArZ+Y/MhEfNXgKeTIHuIXMaFe86ekTxYxfIziH5VpGtIzeVxXE4teNNI/tpSX
|
15
|
+
DcBNspVsx4N/PBqVdtD2KqTO+yrHiER7T9XEEctMgmFQB+NGMLNIpde1tGS8hX2p
|
16
|
+
mcWzr4EAsJwbtLa3HHPwNrr3+Xj1YA8SvLffsJ0nUv/DeqkDCr/CG8mfPO65KtvX
|
17
|
+
rp7h6AAaApIXd1JOn/ady0QxBNc9Rcjg0iG3lF4bRozRR2/B3cNC9PlHUhObWLYh
|
18
|
+
/fYRy+X91OOKL0AyBJRoXo4iT7YeerdeYuWB9HZjJZSR13qeIn2vgJOS4qpPgqyu
|
19
|
+
S0VfcA==
|
20
|
+
-----END CERTIFICATE-----
|
File without changes
|
data/config/nacl_ffi.yml
CHANGED
@@ -5,8 +5,8 @@
|
|
5
5
|
- KEYBYTES
|
6
6
|
|
7
7
|
:functions:
|
8
|
-
~ : [
|
9
|
-
:verify: [
|
8
|
+
~ : [ pointer, pointer, ulong_long, pointer, int ]
|
9
|
+
:verify: [ pointer, pointer, ulong_long, pointer, int ]
|
10
10
|
|
11
11
|
:primitives:
|
12
12
|
- :HMACSHA512256
|
@@ -24,12 +24,12 @@
|
|
24
24
|
- MACBYTES
|
25
25
|
|
26
26
|
:functions:
|
27
|
-
~ : [
|
28
|
-
:open : [
|
29
|
-
:keypair : [
|
30
|
-
:beforenm : [
|
31
|
-
:afternm : [
|
32
|
-
:open_afternm: [
|
27
|
+
~ : [ pointer, pointer, ulong_long, pointer, pointer, pointer, int ]
|
28
|
+
:open : [ pointer, pointer, ulong_long, pointer, pointer, pointer, int ]
|
29
|
+
:keypair : [ pointer, pointer, int ]
|
30
|
+
:beforenm : [ pointer, pointer, pointer, int ]
|
31
|
+
:afternm : [ pointer, pointer, ulong_long, pointer, pointer, int ]
|
32
|
+
:open_afternm: [ pointer, pointer, ulong_long, pointer, pointer, int ]
|
33
33
|
|
34
34
|
:primitives:
|
35
35
|
- :Curve25519XSalsa20Poly1305
|
@@ -40,7 +40,7 @@
|
|
40
40
|
- BYTES
|
41
41
|
|
42
42
|
:functions:
|
43
|
-
~: [
|
43
|
+
~: [ pointer, pointer, ulong_long, int ]
|
44
44
|
|
45
45
|
:primitives:
|
46
46
|
- :SHA512
|
@@ -53,8 +53,8 @@
|
|
53
53
|
- KEYBYTES
|
54
54
|
|
55
55
|
:functions:
|
56
|
-
~ : [
|
57
|
-
:verify: [
|
56
|
+
~ : [ pointer, pointer, ulong_long, pointer, int ]
|
57
|
+
:verify: [ pointer, pointer, ulong_long, pointer, int ]
|
58
58
|
|
59
59
|
:primitives:
|
60
60
|
- :Poly1305
|
@@ -68,8 +68,8 @@
|
|
68
68
|
- BOXZEROBYTES
|
69
69
|
|
70
70
|
:functions:
|
71
|
-
~ : [
|
72
|
-
:open: [
|
71
|
+
~ : [ pointer, pointer, ulong_long, pointer, pointer, int ]
|
72
|
+
:open: [ pointer, pointer, ulong_long, pointer, pointer, int ]
|
73
73
|
|
74
74
|
:primitives:
|
75
75
|
- :XSalsa20Poly1305
|
@@ -82,9 +82,9 @@
|
|
82
82
|
- SECRETKEYBYTES
|
83
83
|
|
84
84
|
:functions:
|
85
|
-
~ : [
|
86
|
-
open : [
|
87
|
-
keypair: [
|
85
|
+
~ : [ pointer, pointer, pointer, ulong_long, pointer, int ]
|
86
|
+
open : [ pointer, pointer, pointer, ulong_long, pointer, int ]
|
87
|
+
keypair: [ pointer, pointer, int ]
|
88
88
|
|
89
89
|
:primitives:
|
90
90
|
- :Ed25519
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#
|
2
|
+
# FIXME: workaround for JRuby 1.7.4, where C extensions are
|
3
|
+
# disabled. This can be removed, apparently, when 1.7.5 is released.
|
4
|
+
#
|
5
|
+
if defined? ENV_JAVA
|
6
|
+
ENV_JAVA['jruby.cext.enabled'] = 'true'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'mkmf'
|
10
|
+
|
11
|
+
create_makefile('sodium/ffi/memory')
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#include <stddef.h>
|
2
|
+
|
3
|
+
void
|
4
|
+
sodium_memxor(unsigned char *out, unsigned char *buf1, unsigned char *buf2, size_t size) {
|
5
|
+
size_t i;
|
6
|
+
for(i = 0; i < size; i++)
|
7
|
+
out[i] = buf1[i] ^ buf2[i];
|
8
|
+
}
|
9
|
+
|
10
|
+
void
|
11
|
+
sodium_memput(unsigned char *out, unsigned char *in, size_t offset, size_t size) {
|
12
|
+
size_t i;
|
13
|
+
for (i = 0; i < size; i++) {
|
14
|
+
out[offset + i] = in[i];
|
15
|
+
}
|
16
|
+
}
|
data/lib/sodium/auth.rb
CHANGED
@@ -7,35 +7,45 @@ class Sodium::Auth
|
|
7
7
|
Sodium::Buffer.key self.implementation[:KEYBYTES]
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def auth(message)
|
15
|
-
message = self.class._message(message)
|
10
|
+
def self.auth(key, message)
|
11
|
+
key = self._key(key)
|
12
|
+
message = self._message(message)
|
16
13
|
|
17
14
|
Sodium::Buffer.empty self.implementation[:BYTES] do |authenticator|
|
18
15
|
self.implementation.nacl(
|
19
16
|
authenticator.to_str,
|
20
17
|
message.to_str,
|
21
18
|
message.to_str.bytesize,
|
22
|
-
|
19
|
+
key.to_str
|
23
20
|
) or raise Sodium::CryptoError, 'failed to generate an authenticator'
|
24
21
|
end
|
25
22
|
end
|
26
23
|
|
27
|
-
def verify(message, authenticator)
|
28
|
-
|
29
|
-
|
24
|
+
def self.verify(key, message, authenticator)
|
25
|
+
key = self._key(key)
|
26
|
+
message = self._message(message)
|
27
|
+
authenticator = self._authenticator(authenticator)
|
30
28
|
|
31
29
|
self.implementation.nacl_verify(
|
32
30
|
authenticator.to_str,
|
33
31
|
message.to_str,
|
34
32
|
message.to_str.bytesize,
|
35
|
-
|
33
|
+
key.to_str
|
36
34
|
)
|
37
35
|
end
|
38
36
|
|
37
|
+
def initialize(key)
|
38
|
+
@key = self.class._key(key)
|
39
|
+
end
|
40
|
+
|
41
|
+
def auth(message)
|
42
|
+
self.class.auth(@key, message)
|
43
|
+
end
|
44
|
+
|
45
|
+
def verify(message, authenticator)
|
46
|
+
self.class.verify(@key, message, authenticator)
|
47
|
+
end
|
48
|
+
|
39
49
|
private
|
40
50
|
|
41
51
|
def self._key(k)
|
data/lib/sodium/box.rb
CHANGED
@@ -28,7 +28,7 @@ class Sodium::Box
|
|
28
28
|
nonce.to_str,
|
29
29
|
shared_key.to_str
|
30
30
|
) or raise Sodium::CryptoError, 'failed to close the box'
|
31
|
-
end.
|
31
|
+
end.ldrop self.implementation[:BOXZEROBYTES]
|
32
32
|
end
|
33
33
|
|
34
34
|
def self.open_afternm(shared_key, ciphertext, nonce)
|
@@ -44,7 +44,7 @@ class Sodium::Box
|
|
44
44
|
nonce.to_str,
|
45
45
|
shared_key.to_str
|
46
46
|
) or raise Sodium::CryptoError, 'failed to open the box'
|
47
|
-
end.
|
47
|
+
end.ldrop self.implementation[:ZEROBYTES]
|
48
48
|
end
|
49
49
|
|
50
50
|
|
@@ -70,7 +70,7 @@ class Sodium::Box
|
|
70
70
|
@public_key.to_str,
|
71
71
|
@secret_key.to_str
|
72
72
|
) or raise Sodium::CryptoError, 'failed to close the box'
|
73
|
-
end.
|
73
|
+
end.ldrop self.implementation[:BOXZEROBYTES]
|
74
74
|
end
|
75
75
|
|
76
76
|
def open(ciphertext, nonce)
|
@@ -86,7 +86,7 @@ class Sodium::Box
|
|
86
86
|
@public_key.to_str,
|
87
87
|
@secret_key.to_str
|
88
88
|
) or raise Sodium::CryptoError, 'failed to open the box'
|
89
|
-
end.
|
89
|
+
end.ldrop self.implementation[:ZEROBYTES]
|
90
90
|
end
|
91
91
|
|
92
92
|
def beforenm
|
@@ -114,11 +114,11 @@ class Sodium::Box
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def self._message(m)
|
117
|
-
Sodium::Buffer.
|
117
|
+
Sodium::Buffer.lpad m, self.implementation[:ZEROBYTES]
|
118
118
|
end
|
119
119
|
|
120
120
|
def self._ciphertext(c)
|
121
|
-
Sodium::Buffer.
|
121
|
+
Sodium::Buffer.lpad c, self.implementation[:BOXZEROBYTES]
|
122
122
|
end
|
123
123
|
|
124
124
|
def self._nonce(n)
|
data/lib/sodium/buffer.rb
CHANGED
@@ -14,6 +14,30 @@ class Sodium::Buffer
|
|
14
14
|
self.new("\0" * size).tap {|buffer| yield buffer if block_given? }
|
15
15
|
end
|
16
16
|
|
17
|
+
def self.ljust(string, size)
|
18
|
+
size = (size > string.bytesize) ? size : string.bytesize
|
19
|
+
|
20
|
+
self.empty(size) do |buffer|
|
21
|
+
buffer[0, string.bytesize] = string
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.rjust(string, size)
|
26
|
+
size = (size > string.bytesize) ? size : string.bytesize
|
27
|
+
|
28
|
+
self.empty(size) do |buffer|
|
29
|
+
buffer[size - string.bytesize, string.bytesize] = string
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.lpad(string, size, &block)
|
34
|
+
self.rjust(string, string.bytesize + size, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.rpad(string, size, &block)
|
38
|
+
self.ljust(string, string.bytesize + size, &block)
|
39
|
+
end
|
40
|
+
|
17
41
|
def self.new(bytes, size = bytes.bytesize)
|
18
42
|
raise Sodium::LengthError, "buffer must be exactly #{size} bytes long" unless
|
19
43
|
bytes.bytesize == size
|
@@ -37,26 +61,67 @@ class Sodium::Buffer
|
|
37
61
|
|
38
62
|
ObjectSpace.define_finalizer self,
|
39
63
|
self.class._finalizer(@bytes)
|
64
|
+
|
65
|
+
self.freeze
|
40
66
|
end
|
41
67
|
|
42
|
-
def
|
43
|
-
Sodium::Buffer.new(
|
44
|
-
|
45
|
-
|
46
|
-
|
68
|
+
def ==(bytes)
|
69
|
+
bytes = Sodium::Buffer.new(bytes)
|
70
|
+
|
71
|
+
return false unless
|
72
|
+
self.bytesize == bytes.bytesize
|
73
|
+
|
74
|
+
Sodium::FFI::Crypto.sodium_memcmp(
|
75
|
+
self.to_str,
|
76
|
+
bytes.to_str,
|
77
|
+
bytes.bytesize
|
78
|
+
) == 0
|
47
79
|
end
|
48
80
|
|
49
|
-
def
|
50
|
-
self.
|
51
|
-
|
52
|
-
|
81
|
+
def +(bytes)
|
82
|
+
Sodium::Buffer.empty(self.bytesize + bytes.bytesize) do |buffer|
|
83
|
+
buffer[0, self .bytesize] = self
|
84
|
+
buffer[self.bytesize, bytes.bytesize] = bytes
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def ^(bytes)
|
89
|
+
bytes = Sodium::Buffer.new(bytes)
|
90
|
+
|
91
|
+
raise ArgumentError, %{must only XOR strings of equal length} unless
|
92
|
+
self.bytesize == bytes.bytesize
|
93
|
+
|
94
|
+
Sodium::Buffer.empty(self.bytesize) do |buffer|
|
95
|
+
Sodium::FFI::Memory.sodium_memxor(
|
96
|
+
buffer.to_str,
|
97
|
+
self.to_str,
|
98
|
+
bytes.to_str,
|
99
|
+
bytes.bytesize
|
100
|
+
)
|
101
|
+
end
|
53
102
|
end
|
54
103
|
|
55
|
-
def
|
56
|
-
|
104
|
+
def []=(offset, size, bytes)
|
105
|
+
raise ArgumentError, %{must only assign to existing bytes in the buffer} unless
|
106
|
+
self.bytesize >= offset + size
|
107
|
+
|
108
|
+
raise ArgumentError, %{must reassign only a fixed number of bytes} unless
|
109
|
+
size == bytes.bytesize
|
110
|
+
|
111
|
+
# ensure the original bytes get cleared
|
112
|
+
bytes = Sodium::Buffer.new(bytes)
|
113
|
+
|
114
|
+
Sodium::FFI::Memory.sodium_memput(
|
115
|
+
self.to_str,
|
116
|
+
bytes.to_str,
|
117
|
+
offset,
|
118
|
+
size
|
119
|
+
)
|
120
|
+
|
121
|
+
true
|
57
122
|
end
|
58
123
|
|
59
|
-
def
|
124
|
+
def [](*args)
|
60
125
|
return self.class.new(
|
61
126
|
@bytes.byteslice(*args).to_s
|
62
127
|
) if (
|
@@ -103,6 +168,9 @@ class Sodium::Buffer
|
|
103
168
|
finish += self.bytesize if finish < 0
|
104
169
|
size = finish - start + 1
|
105
170
|
|
171
|
+
# this approach ensures the bytes are copied into new memory, so
|
172
|
+
# instantiating a new buffer doesn't clear the bytes in the
|
173
|
+
# existing buffer
|
106
174
|
bytes = (start >= 0 and size >= 0) ?
|
107
175
|
@bytes.unpack("@#{start}a#{size}").first :
|
108
176
|
''
|
@@ -110,10 +178,20 @@ class Sodium::Buffer
|
|
110
178
|
self.class.new(bytes)
|
111
179
|
end
|
112
180
|
|
181
|
+
alias byteslice []
|
182
|
+
|
113
183
|
def bytesize
|
114
184
|
@bytes.bytesize
|
115
185
|
end
|
116
186
|
|
187
|
+
def rdrop(size)
|
188
|
+
self[0, self.bytesize - size]
|
189
|
+
end
|
190
|
+
|
191
|
+
def ldrop(size)
|
192
|
+
self[size, self.bytesize - size]
|
193
|
+
end
|
194
|
+
|
117
195
|
def inspect
|
118
196
|
# this appears to be equivalent to the default Object#inspect,
|
119
197
|
# albeit without instance variables
|
data/lib/sodium/ffi.rb
CHANGED
data/lib/sodium/ffi/crypto.rb
CHANGED
@@ -92,8 +92,9 @@ module Sodium::FFI::Crypto
|
|
92
92
|
|
93
93
|
ffi_lib 'sodium'
|
94
94
|
|
95
|
-
attach_function 'sodium_init', [],
|
96
|
-
attach_function 'sodium_memzero', [:pointer, :size_t],
|
95
|
+
attach_function 'sodium_init', [], :void
|
96
|
+
attach_function 'sodium_memzero', [:pointer, :size_t], :void
|
97
|
+
attach_function 'sodium_memcmp', [:pointer, :pointer, :size_t], :int
|
97
98
|
|
98
99
|
sodium_init
|
99
100
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Sodium::FFI::Memory
|
4
|
+
extend FFI::Library
|
5
|
+
|
6
|
+
ffi_lib Pathname.new(__FILE__).dirname.join(
|
7
|
+
%{memory.#{RbConfig::MAKEFILE_CONFIG['DLEXT']}}
|
8
|
+
)
|
9
|
+
|
10
|
+
attach_function 'sodium_memxor', [:pointer, :pointer, :pointer, :size_t ], :void
|
11
|
+
attach_function 'sodium_memput', [:pointer, :pointer, :size_t, :size_t ], :void
|
12
|
+
end
|
data/lib/sodium/secret_box.rb
CHANGED
@@ -27,7 +27,7 @@ class Sodium::SecretBox
|
|
27
27
|
nonce.to_str,
|
28
28
|
@key.to_str
|
29
29
|
) or raise Sodium::CryptoError, 'failed to close the secret box'
|
30
|
-
end.
|
30
|
+
end.ldrop self.implementation[:BOXZEROBYTES]
|
31
31
|
end
|
32
32
|
|
33
33
|
def open(ciphertext, nonce)
|
@@ -42,7 +42,7 @@ class Sodium::SecretBox
|
|
42
42
|
nonce.to_str,
|
43
43
|
@key.to_str
|
44
44
|
) or raise Sodium::CryptoError, 'failed to open the secret box'
|
45
|
-
end.
|
45
|
+
end.ldrop self.implementation[:ZEROBYTES]
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
@@ -52,11 +52,11 @@ class Sodium::SecretBox
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def self._message(m)
|
55
|
-
Sodium::Buffer.
|
55
|
+
Sodium::Buffer.lpad m, self.implementation[:ZEROBYTES]
|
56
56
|
end
|
57
57
|
|
58
58
|
def self._ciphertext(c)
|
59
|
-
Sodium::Buffer.
|
59
|
+
Sodium::Buffer.lpad c, self.implementation[:BOXZEROBYTES]
|
60
60
|
end
|
61
61
|
|
62
62
|
def self._nonce(n)
|
data/sodium.gemspec
CHANGED
@@ -10,14 +10,19 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.description = 'A library for performing cryptography based on modern ciphers and protocols'
|
11
11
|
|
12
12
|
gem.bindir = 'bin'
|
13
|
-
gem.files = `git ls-files`
|
14
|
-
gem.
|
15
|
-
gem.
|
16
|
-
gem.test_files = `git ls-files -- spec/*`
|
13
|
+
gem.files = `git ls-files` .split("\n")
|
14
|
+
gem.executables = `git ls-files -- bin/*` .split("\n").map {|e| File.basename(e) }
|
15
|
+
gem.extensions = `git ls-files -- ext/**/*.rb`.split("\n")
|
16
|
+
gem.test_files = `git ls-files -- spec/*` .split("\n")
|
17
|
+
|
18
|
+
gem.requirements << 'libsodium ~> 0.5'
|
17
19
|
|
18
20
|
gem.add_dependency 'ffi', '~> 1'
|
19
21
|
|
20
22
|
gem.add_development_dependency 'rake', '~> 10'
|
21
23
|
gem.add_development_dependency 'minitest', '~> 5'
|
22
24
|
gem.add_development_dependency 'version', '~> 1'
|
25
|
+
|
26
|
+
gem.signing_key = '/Volumes/Sensitive/Keys/Gems/sodium@touset.org.key'
|
27
|
+
gem.cert_chain = [ 'certs/sodium@touset.org.cert' ]
|
23
28
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
namespace :compile do
|
2
|
+
LIB_PATH = File.expand_path('../../lib', __FILE__)
|
3
|
+
EXT_PATH = File.expand_path('../../ext/sodium', __FILE__)
|
4
|
+
|
5
|
+
MEMORY_PATH = File.join EXT_PATH, 'memory'
|
6
|
+
MEMORY_SRC = File.join MEMORY_PATH, '*.c'
|
7
|
+
MEMORY_LIB = 'memory.' + RbConfig::CONFIG['DLEXT']
|
8
|
+
|
9
|
+
desc 'Compile the memory extension'
|
10
|
+
task :memory => %{#{LIB_PATH}/sodium/ffi/#{MEMORY_LIB}}
|
11
|
+
|
12
|
+
file %{#{LIB_PATH}/sodium/ffi/#{MEMORY_LIB}} => %{#{MEMORY_PATH}/Makefile} do
|
13
|
+
sh %{make -C #{MEMORY_PATH} install sitearchdir="#{LIB_PATH}"}
|
14
|
+
end
|
15
|
+
|
16
|
+
file %{#{MEMORY_PATH}/Makefile} => FileList[MEMORY_SRC] do
|
17
|
+
Dir.chdir(MEMORY_PATH) { ruby %{extconf.rb} }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Compile all native extensions'
|
22
|
+
task :compile => %w{ compile:memory }
|
23
|
+
|
24
|
+
task :test => %w{ compile }
|
@@ -33,12 +33,23 @@ describe Sodium::Auth::HMACSHA256 do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'must generate authenticators' do
|
36
|
+
self.klass.auth(
|
37
|
+
self.key,
|
38
|
+
self.plaintext
|
39
|
+
).to_str.must_equal self.authenticator
|
40
|
+
|
36
41
|
self.subject.auth(
|
37
42
|
self.plaintext
|
38
43
|
).to_str.must_equal self.authenticator
|
39
44
|
end
|
40
45
|
|
41
46
|
it 'must verify authenticators' do
|
47
|
+
self.klass.verify(
|
48
|
+
self.key,
|
49
|
+
self.plaintext,
|
50
|
+
self.authenticator
|
51
|
+
).must_equal true
|
52
|
+
|
42
53
|
self.subject.verify(
|
43
54
|
self.plaintext,
|
44
55
|
self.authenticator
|
@@ -32,12 +32,23 @@ describe Sodium::Auth::HMACSHA512256 do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'must generate authenticators' do
|
35
|
+
self.klass.auth(
|
36
|
+
self.key,
|
37
|
+
self.plaintext
|
38
|
+
).to_str.must_equal self.authenticator
|
39
|
+
|
35
40
|
self.subject.auth(
|
36
41
|
self.plaintext
|
37
42
|
).to_str.must_equal self.authenticator
|
38
43
|
end
|
39
44
|
|
40
45
|
it 'must verify authenticators' do
|
46
|
+
self.klass.verify(
|
47
|
+
self.key,
|
48
|
+
self.plaintext,
|
49
|
+
self.authenticator
|
50
|
+
).must_equal true
|
51
|
+
|
41
52
|
self.subject.verify(
|
42
53
|
self.plaintext,
|
43
54
|
self.authenticator
|
data/test/sodium/buffer_test.rb
CHANGED
@@ -37,6 +37,32 @@ describe Sodium::Buffer do
|
|
37
37
|
mock.verify
|
38
38
|
end
|
39
39
|
|
40
|
+
it '::ljust must pad zero bytes on the end' do
|
41
|
+
subject.ljust('xyz', 5).to_str.must_equal "xyz\0\0"
|
42
|
+
end
|
43
|
+
|
44
|
+
it '::ljust must not pad bytes when not needed' do
|
45
|
+
subject.ljust('xyz', 2).to_str.must_equal 'xyz'
|
46
|
+
end
|
47
|
+
|
48
|
+
it '::rjust must pad zero bytes onto the front' do
|
49
|
+
subject.rjust('xyz', 5).to_str.must_equal "\0\0xyz"
|
50
|
+
end
|
51
|
+
|
52
|
+
it '::rjust must not pad bytes when not needed' do
|
53
|
+
subject.rjust('xyz', 2).to_str.must_equal 'xyz'
|
54
|
+
end
|
55
|
+
|
56
|
+
it '::lpad must prepend the required number of bytes' do
|
57
|
+
subject.lpad('xyz', 0).to_str.must_equal 'xyz'
|
58
|
+
subject.lpad('xyz', 2).to_str.must_equal "\0\0xyz"
|
59
|
+
end
|
60
|
+
|
61
|
+
it '::rpad must append the required number of bytes' do
|
62
|
+
subject.rpad('xyz', 0).to_str.must_equal 'xyz'
|
63
|
+
subject.rpad('xyz', 2).to_str.must_equal "xyz\0\0"
|
64
|
+
end
|
65
|
+
|
40
66
|
it '::new must create a buffer containing the specified string' do
|
41
67
|
subject.new('xyz' ).to_str.must_equal('xyz')
|
42
68
|
subject.new('xyz' * 50).to_str.must_equal('xyz' * 50)
|
@@ -60,56 +86,87 @@ describe Sodium::Buffer do
|
|
60
86
|
it '#initialize must wipe the buffer during finalization'
|
61
87
|
it '#initialize must prevent the string from being paged to disk'
|
62
88
|
|
63
|
-
it '
|
64
|
-
subject.new('
|
89
|
+
it '#== must compare equality of two buffers' do
|
90
|
+
subject.new('xyz').==('xyz') .must_equal true
|
91
|
+
subject.new('xyz').==('xy') .must_equal false
|
92
|
+
subject.new('xyz').==('xyzz').must_equal false
|
93
|
+
subject.new('xyz').==('abc') .must_equal false
|
65
94
|
end
|
66
95
|
|
67
|
-
it '
|
68
|
-
|
96
|
+
it '#== must compare equality of two buffers in constant time'
|
97
|
+
|
98
|
+
it '#+ must append two buffers' do
|
99
|
+
subject.new('xyz').+('abc').to_str.must_equal 'xyzabc'
|
100
|
+
end
|
101
|
+
|
102
|
+
it '#^ must XOR two buffers' do
|
103
|
+
subject.new('xyz').^('xyz').to_str.must_equal "\0\0\0"
|
104
|
+
subject.new('xyz').^('xyz').to_str.must_equal "\0\0\0"
|
69
105
|
end
|
70
106
|
|
71
|
-
it '#
|
107
|
+
it '#[]= must allow replacement of byte ranges' do
|
108
|
+
subject.new('xyz').tap {|b| b[0, 3] = 'abc' }.to_str.must_equal 'abc'
|
109
|
+
subject.new('xyz').tap {|b| b[0, 2] = 'ab' }.to_str.must_equal 'abz'
|
110
|
+
subject.new('xyz').tap {|b| b[2, 1] = 'c' }.to_str.must_equal 'xyc'
|
111
|
+
end
|
112
|
+
|
113
|
+
it '#[]= must not allow resizing the buffer' do
|
114
|
+
lambda { subject.new('xyz')[0, 1] = 'ab' }.must_raise ArgumentError
|
115
|
+
lambda { subject.new('xyz')[0, 2] = 'a' }.must_raise ArgumentError
|
116
|
+
lambda { subject.new('xyz')[3, 1] = 'a' }.must_raise ArgumentError
|
117
|
+
lambda { subject.new('xyz')[2, 2] = 'ab' }.must_raise ArgumentError
|
118
|
+
end
|
119
|
+
|
120
|
+
it '#[] must accept an indivdual byte offset to return' do
|
72
121
|
subject.new('xyz').tap do |buffer|
|
73
|
-
buffer
|
74
|
-
buffer
|
75
|
-
buffer
|
76
|
-
buffer
|
77
|
-
buffer
|
78
|
-
buffer
|
79
|
-
buffer
|
80
|
-
buffer
|
122
|
+
buffer[-4].to_str.must_equal ''
|
123
|
+
buffer[-3].to_str.must_equal 'x'
|
124
|
+
buffer[-2].to_str.must_equal 'y'
|
125
|
+
buffer[-1].to_str.must_equal 'z'
|
126
|
+
buffer[ 0].to_str.must_equal 'x'
|
127
|
+
buffer[ 1].to_str.must_equal 'y'
|
128
|
+
buffer[ 2].to_str.must_equal 'z'
|
129
|
+
buffer[ 3].to_str.must_equal ''
|
81
130
|
end
|
82
131
|
end
|
83
132
|
|
84
|
-
it '#
|
133
|
+
it '#[] must accept ranges of bytes to return' do
|
85
134
|
subject.new('xyz').tap do |buffer|
|
86
|
-
buffer
|
87
|
-
buffer
|
88
|
-
buffer
|
89
|
-
buffer
|
90
|
-
buffer
|
91
|
-
buffer
|
92
|
-
buffer
|
93
|
-
buffer
|
135
|
+
buffer[ 0.. 0].to_str.must_equal 'x'
|
136
|
+
buffer[ 0.. 1].to_str.must_equal 'xy'
|
137
|
+
buffer[ 0.. 2].to_str.must_equal 'xyz'
|
138
|
+
buffer[ 0.. 3].to_str.must_equal 'xyz'
|
139
|
+
buffer[ 1..-1].to_str.must_equal 'yz'
|
140
|
+
buffer[ 2..-2].to_str.must_equal ''
|
141
|
+
buffer[-3..-1].to_str.must_equal 'xyz'
|
142
|
+
buffer[-4.. 1].to_str.must_equal ''
|
94
143
|
end
|
95
144
|
end
|
96
145
|
|
97
|
-
it '#
|
146
|
+
it '#[] must accept an offset and number of bytes to return' do
|
98
147
|
subject.new('xyz').tap do |buffer|
|
99
|
-
buffer
|
100
|
-
buffer
|
101
|
-
buffer
|
102
|
-
buffer
|
103
|
-
buffer
|
104
|
-
buffer
|
105
|
-
buffer
|
148
|
+
buffer[ 0, 0].to_str.must_equal ''
|
149
|
+
buffer[ 0, 1].to_str.must_equal 'x'
|
150
|
+
buffer[ 0, 3].to_str.must_equal 'xyz'
|
151
|
+
buffer[ 2, 4].to_str.must_equal 'z'
|
152
|
+
buffer[ 2, 1].to_str.must_equal 'z'
|
153
|
+
buffer[-2, 1].to_str.must_equal 'y'
|
154
|
+
buffer[ 0, -1].to_str.must_equal ''
|
106
155
|
end
|
107
156
|
end
|
108
157
|
|
109
|
-
it '#
|
158
|
+
it '#[] must return its length' do
|
110
159
|
subject.new('testing').bytesize.must_equal 7
|
111
160
|
end
|
112
161
|
|
162
|
+
it '#ldrop must drop bytes off the left' do
|
163
|
+
subject.new('xyz').ldrop(2).to_str.must_equal('z')
|
164
|
+
end
|
165
|
+
|
166
|
+
it '#rdrop must drop bytes off the right' do
|
167
|
+
subject.new('xyz').rdrop(2).to_str.must_equal('x')
|
168
|
+
end
|
169
|
+
|
113
170
|
it '#inspect must not reveal its instance variables' do
|
114
171
|
subject.new('blah').inspect.wont_include 'blah'
|
115
172
|
end
|
metadata
CHANGED
@@ -1,15 +1,36 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sodium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Stephen Touset
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
|
-
cert_chain:
|
12
|
-
|
11
|
+
cert_chain:
|
12
|
+
- |
|
13
|
+
-----BEGIN CERTIFICATE-----
|
14
|
+
MIIDMDCCAhigAwIBAgIBADANBgkqhkiG9w0BAQUFADA+MQ8wDQYDVQQDDAZzb2Rp
|
15
|
+
dW0xFjAUBgoJkiaJk/IsZAEZFgZ0b3VzZXQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
16
|
+
HhcNMTMwNjI4MDEzMzQ4WhcNMTQwNjI4MDEzMzQ4WjA+MQ8wDQYDVQQDDAZzb2Rp
|
17
|
+
dW0xFjAUBgoJkiaJk/IsZAEZFgZ0b3VzZXQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
18
|
+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCh3C2P1jW4MvcpXioNkqW/
|
19
|
+
HiD9ZpTew1tHTolQclBBmOmOApLUPc9PIsfbohph83Z82x+BWbjEdL5NAfEQjRVu
|
20
|
+
O8JUBJh0YRDF9P7fDtd9w0b3mmhumujbEsmDYs1ru5VvjgCh+Hfxgddlpha0KmxQ
|
21
|
+
0j3h/Uj27tFbE33dIRqb5dBBBnnIM5CqRMu5/gDeXN5GrjYK3JfZlzZRECjnfuR5
|
22
|
+
qDqoQFJK5ZmaEFm9E88HdAIS+sV9zb1OCYlADr3EB/a3Shxedx4SsX7oBPyNfsRb
|
23
|
+
kMdTr+VynH/OEPSo0dW1DuKpUCmNBscrTOwhn6hJUDNpr6f0CTfYG9jGJY3p5JMt
|
24
|
+
AgMBAAGjOTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFIu3aZS82t6UR4Z5eON3t2LI
|
25
|
+
AHPeMAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAkjXdsFKC9mQfT3tP
|
26
|
+
PNtArZ+Y/MhEfNXgKeTIHuIXMaFe86ekTxYxfIziH5VpGtIzeVxXE4teNNI/tpSX
|
27
|
+
DcBNspVsx4N/PBqVdtD2KqTO+yrHiER7T9XEEctMgmFQB+NGMLNIpde1tGS8hX2p
|
28
|
+
mcWzr4EAsJwbtLa3HHPwNrr3+Xj1YA8SvLffsJ0nUv/DeqkDCr/CG8mfPO65KtvX
|
29
|
+
rp7h6AAaApIXd1JOn/ady0QxBNc9Rcjg0iG3lF4bRozRR2/B3cNC9PlHUhObWLYh
|
30
|
+
/fYRy+X91OOKL0AyBJRoXo4iT7YeerdeYuWB9HZjJZSR13qeIn2vgJOS4qpPgqyu
|
31
|
+
S0VfcA==
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
date: 2013-06-28 00:00:00.000000000 Z
|
13
34
|
dependencies:
|
14
35
|
- !ruby/object:Gem::Dependency
|
15
36
|
name: ffi
|
@@ -78,16 +99,22 @@ dependencies:
|
|
78
99
|
description: A library for performing cryptography based on modern ciphers and protocols
|
79
100
|
email: stephen@touset.org
|
80
101
|
executables: []
|
81
|
-
extensions:
|
102
|
+
extensions:
|
103
|
+
- ext/sodium/memory/extconf.rb
|
82
104
|
extra_rdoc_files: []
|
83
105
|
files:
|
84
106
|
- .gitignore
|
85
107
|
- .travis.yml
|
108
|
+
- CHANGELOG.md
|
86
109
|
- Gemfile
|
87
110
|
- README.md
|
88
111
|
- Rakefile
|
89
112
|
- VERSION
|
113
|
+
- certs/sodium@touset.org.cert
|
114
|
+
- certs/sodium@touset.org.pub.gpg
|
90
115
|
- config/nacl_ffi.yml
|
116
|
+
- ext/sodium/memory/extconf.rb
|
117
|
+
- ext/sodium/memory/memory.c
|
91
118
|
- lib/sodium.rb
|
92
119
|
- lib/sodium/auth.rb
|
93
120
|
- lib/sodium/box.rb
|
@@ -96,6 +123,7 @@ files:
|
|
96
123
|
- lib/sodium/ffi.rb
|
97
124
|
- lib/sodium/ffi/crypto.rb
|
98
125
|
- lib/sodium/ffi/lib_c.rb
|
126
|
+
- lib/sodium/ffi/memory.rb
|
99
127
|
- lib/sodium/ffi/random.rb
|
100
128
|
- lib/sodium/hash.rb
|
101
129
|
- lib/sodium/one_time_auth.rb
|
@@ -104,7 +132,7 @@ files:
|
|
104
132
|
- lib/sodium/sign.rb
|
105
133
|
- lib/sodium/version.rb
|
106
134
|
- sodium.gemspec
|
107
|
-
-
|
135
|
+
- tasks/extensions.rake
|
108
136
|
- tasks/libsodium.rake
|
109
137
|
- tasks/test.rake
|
110
138
|
- tasks/version.rake
|
@@ -144,7 +172,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
172
|
- - '>='
|
145
173
|
- !ruby/object:Gem::Version
|
146
174
|
version: '0'
|
147
|
-
requirements:
|
175
|
+
requirements:
|
176
|
+
- libsodium ~> 0.5
|
148
177
|
rubyforge_project:
|
149
178
|
rubygems_version: 1.8.25
|
150
179
|
signing_key:
|
metadata.gz.sig
ADDED
Binary file
|