rbnacl 6.0.0 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +71 -96
- data/README.md +10 -36
- data/lib/rbnacl.rb +4 -0
- data/lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb +1 -1
- data/lib/rbnacl/boxes/sealed.rb +136 -0
- data/lib/rbnacl/init.rb +1 -1
- data/lib/rbnacl/password_hash/argon2.rb +12 -12
- data/lib/rbnacl/signatures/ed25519.rb +3 -3
- data/lib/rbnacl/sodium.rb +14 -9
- data/lib/rbnacl/version.rb +1 -1
- data/spec/rbnacl/boxes/sealed_spec.rb +63 -0
- data/spec/rbnacl/sodium_spec.rb +51 -0
- data/spec/shared/sealed_box.rb +29 -0
- data/spec/spec_helper.rb +1 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15129e7babc37c8c428aca4bedbf8e9577d7ddd6b1f0252de1c4c7e83034368b
|
4
|
+
data.tar.gz: 61a22eaacfd4043a3348db5ed4230745cb8df2d66607a39392e6b9dde0c817fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c43e06b87c005bc4b3086df982add673eaae4b6554556fd6b47b89bb14e2da1028e804ef62d3617ba311820d1623948bd0875fd273152c52bd64da96452fc67d
|
7
|
+
data.tar.gz: 7cfaff058fbc58386614e9efe0d62ef47f550f6e571e6c1ff3f887627d36c95e05be295fabc52fea5bd739db21e9249606db8317d8038db3bf0907bd23d9106b
|
data/CHANGES.md
CHANGED
@@ -1,148 +1,123 @@
|
|
1
|
-
## [6.0.
|
2
|
-
|
3
|
-
[6.0.0]: https://github.com/crypto-rb/rbnacl/pull/182
|
1
|
+
## [6.0.1] (2019-01-27)
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
- Add fallback `sodium_constants` for Argon2 ([#189])
|
4
|
+
- Support libsodium versions used by Heroku ([#186])
|
5
|
+
- Sealed boxes ([#184])
|
8
6
|
|
9
|
-
|
10
|
-
Add support for XChaCha20-Poly1305.
|
11
|
-
([@AnIrishDuck])
|
12
|
-
|
13
|
-
* [#174](https://github.com/crypto-rb/rbnacl/pull/174)
|
14
|
-
Fix buffer size type in `randombytes_buf` binding.
|
15
|
-
([@elijh])
|
16
|
-
|
17
|
-
* [#172](https://github.com/crypto-rb/rbnacl/pull/172)
|
18
|
-
Add support for argon2id digest.
|
19
|
-
([@trofi])
|
7
|
+
## [6.0.0] (2018-11-08)
|
20
8
|
|
21
|
-
|
22
|
-
|
23
|
-
|
9
|
+
- Deprecate rbnacl-libsodium ([#180])
|
10
|
+
- Add support for XChaCha20-Poly1305 ([#176])
|
11
|
+
- Fix buffer size type in `randombytes_buf` binding ([#174])
|
12
|
+
- Add support for argon2id digest ([#174])
|
13
|
+
- Support for non-32-byte HMAC-SHA256/512 keys ([#166])
|
24
14
|
|
25
15
|
## 5.0.0 (2017-06-13)
|
26
16
|
|
27
|
-
|
28
|
-
Support the BLAKE2b Initialize-Update-Finalize API.
|
29
|
-
([@fudanchii])
|
17
|
+
- Support the BLAKE2b Initialize-Update-Finalize API ([#159])
|
30
18
|
|
31
19
|
## 4.0.2 (2017-03-12)
|
32
20
|
|
33
|
-
|
34
|
-
Raise error on degenerate keys (fixes #152).
|
35
|
-
([@paragonie-scott], [@tarcieri])
|
21
|
+
- Raise error on degenerate keys. Fixes #152 ([#157])
|
36
22
|
|
37
23
|
## 4.0.1 (2016-12-04)
|
38
24
|
|
39
|
-
|
40
|
-
Last minute changes to the ChaCha20Poly1305 API.
|
41
|
-
([@tarcieri])
|
25
|
+
- Last minute changes to the ChaCha20Poly1305 API ([#148])
|
42
26
|
|
43
27
|
## 4.0.0 (2016-12-04)
|
44
28
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
* [#142](https://github.com/crypto-rb/rbnacl/pull/142)
|
50
|
-
Added support for Argon2 password hash.
|
51
|
-
([@elijh])
|
52
|
-
|
53
|
-
* [#143](https://github.com/crypto-rb/rbnacl/pull/143)
|
54
|
-
Require Ruby 2.2.6+.
|
55
|
-
([@tarcieri])
|
29
|
+
- Add wrappers for ChaCha20Poly1305 AEAD ciphers ([#141])
|
30
|
+
- Added support for Argon2 password hash ([#142])
|
31
|
+
- Require Ruby 2.2.6+ ([#143])
|
56
32
|
|
57
33
|
## 3.4.0 (2015-05-07)
|
58
34
|
|
59
|
-
|
60
|
-
|
61
|
-
([@grempe])
|
62
|
-
|
63
|
-
* [#137](https://github.com/crypto-rb/rbnacl/pull/137)
|
64
|
-
Expose HMAC-SHA512 (with 64-byte keys)
|
65
|
-
([@mwpastore])
|
35
|
+
- Expose `RbNaCl::Signatures::Ed25519#keypair_bytes` ([#135])
|
36
|
+
- Expose HMAC-SHA512 with 64-byte keys ([#137])
|
66
37
|
|
67
38
|
## 3.3.0 (2015-12-29)
|
68
39
|
|
69
|
-
|
70
|
-
|
71
|
-
([@namelessjon])
|
72
|
-
|
73
|
-
* [#128](https://github.com/crypto-rb/rbnacl/pull/128)
|
74
|
-
Remove use of Thread.exclusive when initializing library.
|
75
|
-
([@tarcieri])
|
40
|
+
- Remove use of Thread.exclusive when initializing library ([#128])
|
41
|
+
- Add salt/personalisation strings for Blake2b ([#105])
|
76
42
|
|
77
43
|
## 3.2.0 (2015-05-31)
|
78
44
|
|
79
|
-
|
80
|
-
|
45
|
+
- Fix method signature for blake2b
|
46
|
+
- RuboCop-friendly codebase
|
81
47
|
|
82
48
|
## 3.1.2 (2014-08-30)
|
83
49
|
|
84
|
-
|
50
|
+
- Fix scrypt support with libsodium 0.7.0 (scryptsalsa208sha256)
|
85
51
|
|
86
52
|
## 3.1.1 (2014-06-14)
|
87
53
|
|
88
|
-
|
89
|
-
|
90
|
-
|
54
|
+
- Fix undefined variable warning
|
55
|
+
- RSpec 3 fixups
|
56
|
+
- RuboCop
|
91
57
|
|
92
58
|
## 3.1.0 (2014-05-22)
|
93
59
|
|
94
|
-
|
60
|
+
- The scrypt password hashing function: `RbNaCl::PasswordHash.scrypt`
|
95
61
|
|
96
62
|
## 3.0.1 (2014-05-12)
|
97
63
|
|
98
|
-
|
64
|
+
- Load gem from `RBNACL_LIBSODIUM_GEM_LIB_PATH` if set. Used by rbnacl-libsodium
|
99
65
|
gem to use libsodium compiled from a gem.
|
100
66
|
|
101
67
|
## 3.0.0 (2014-04-22)
|
102
68
|
|
103
|
-
|
104
|
-
|
69
|
+
- Rename RandomNonceBox to SimpleBox (backwards compatibility preserved)
|
70
|
+
- Reverse documented order of SimpleBox/RandomNonceBox initialize parameters.
|
105
71
|
Technically backwards compatible, but confusing.
|
106
|
-
|
72
|
+
- Ensure all strings are ASCII-8BIT/BINARY encoding prior to use
|
107
73
|
|
108
74
|
## 2.0.0 (2013-11-07)
|
109
75
|
|
110
|
-
|
111
|
-
|
112
|
-
|
76
|
+
- Rename Crypto module to RbNaCl module
|
77
|
+
- Add encrypt/decrypt aliases for `Crypto::RandomNonceBox`
|
78
|
+
- `RbNaCl::VerifyKey#verify` operand order was reversed. New operand order is
|
113
79
|
signature, message instead of message, signature
|
114
|
-
|
115
|
-
all now raise a (descendent of) CryptoError if the check
|
116
|
-
failures are handled by the program.
|
117
|
-
|
118
|
-
which are named after the primitives they provide
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
80
|
+
- `RbNaCL::SecretBox#open`, `RbNaCl::Box#open`, `Auth#verify` and
|
81
|
+
`VerifyKey#verify` all now raise a (descendent of) CryptoError if the check
|
82
|
+
fails. This ensures failures are handled by the program.
|
83
|
+
- `RbNaCl::SecretBox`, Box, etc. are all now aliases for the real
|
84
|
+
implementations, which are named after the primitives they provide
|
85
|
+
- Removed encoder functionality.
|
86
|
+
- Add support for the Blake2b cryptographic hash algorithm.
|
87
|
+
- Add checks that we have a sufficiently recent version of libsodium (0.4.3+)
|
88
|
+
- Dropped ruby-1.8 support
|
89
|
+
- Call the `sodium_init()` function, to select the best algorithms.
|
90
|
+
- Fix some typos in the documentation
|
91
|
+
- Changes in the low level binding for libsodium and removal of the NaCl module
|
92
|
+
- Add a mutex around calls to randombytes in libsodium
|
127
93
|
|
128
94
|
## 1.1.0 (2013-04-19)
|
129
95
|
|
130
|
-
|
96
|
+
- Provide API for querying primitives and details about them, such as key
|
131
97
|
lengths, nonce lengths, etc.
|
132
|
-
|
98
|
+
- Fixed bug on passing null bytes to sha256, sha512 functions.
|
133
99
|
|
134
100
|
## 1.0.0 (2013-03-08)
|
135
101
|
|
136
|
-
|
137
|
-
|
138
|
-
[
|
139
|
-
[
|
140
|
-
[
|
141
|
-
[
|
142
|
-
[
|
143
|
-
[
|
144
|
-
[
|
145
|
-
[
|
146
|
-
[
|
147
|
-
[
|
148
|
-
[
|
102
|
+
- Initial release
|
103
|
+
|
104
|
+
[6.0.1]: https://github.com/crypto-rb/rbnacl/pull/191
|
105
|
+
[#189]: https://github.com/crypto-rb/rbnacl/pull/189
|
106
|
+
[#186]: https://github.com/crypto-rb/rbnacl/pull/186
|
107
|
+
[#184]: https://github.com/crypto-rb/rbnacl/pull/184
|
108
|
+
[6.0.0]: https://github.com/crypto-rb/rbnacl/pull/182
|
109
|
+
[#180]: https://github.com/crypto-rb/rbnacl/pull/180
|
110
|
+
[#176]: https://github.com/crypto-rb/rbnacl/pull/176
|
111
|
+
[#174]: https://github.com/crypto-rb/rbnacl/pull/174
|
112
|
+
[#172]: https://github.com/crypto-rb/rbnacl/pull/172
|
113
|
+
[#166]: https://github.com/crypto-rb/rbnacl/pull/166
|
114
|
+
[#159]: https://github.com/crypto-rb/rbnacl/pull/159
|
115
|
+
[#157]: https://github.com/crypto-rb/rbnacl/pull/157
|
116
|
+
[#148]: https://github.com/crypto-rb/rbnacl/pull/148
|
117
|
+
[#143]: https://github.com/crypto-rb/rbnacl/pull/143
|
118
|
+
[#142]: https://github.com/crypto-rb/rbnacl/pull/142
|
119
|
+
[#141]: https://github.com/crypto-rb/rbnacl/pull/141
|
120
|
+
[#137]: https://github.com/crypto-rb/rbnacl/pull/137
|
121
|
+
[#135]: https://github.com/crypto-rb/rbnacl/pull/135
|
122
|
+
[#128]: https://github.com/crypto-rb/rbnacl/pull/128
|
123
|
+
[#105]: https://github.com/crypto-rb/rbnacl/pull/105
|
data/README.md
CHANGED
@@ -7,26 +7,13 @@
|
|
7
7
|
[](https://github.com/crypto-rb/rbnacl/blob/master/LICENSE.txt)
|
8
8
|
[](https://gitter.im/crypto-rb/Lobby)
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
https://github.com/crypto-rb/rbnacl/tree/4-x-stable
|
14
|
-
|
15
|
-
A Ruby binding to the state-of-the-art [Networking and Cryptography][nacl]
|
16
|
-
library by [Daniel J. Bernstein][djb]. This is **NOT** Google Native Client.
|
17
|
-
This is a crypto library.
|
18
|
-
|
19
|
-
On a completely unrelated topic, RbNaCl is also the empirical formula for
|
20
|
-
Rubidium Sodium Chloride.
|
21
|
-
|
22
|
-
Need help with RbNaCl? Join the [RbNaCl Google Group][group].
|
23
|
-
We're also on IRC at #crypto-rb on irc.freenode.net
|
10
|
+
Ruby binding for [libsodium], a fork of the [Networking and Cryptography][nacl]
|
11
|
+
library.
|
24
12
|
|
13
|
+
[libsodium]: https://libsodium.org
|
25
14
|
[nacl]: http://nacl.cr.yp.to/
|
26
|
-
[djb]: http://cr.yp.to/djb.html
|
27
|
-
[group]: http://groups.google.com/group/rbnacl
|
28
15
|
|
29
|
-
## Why NaCl?
|
16
|
+
## Why libsodium/NaCl?
|
30
17
|
|
31
18
|
NaCl is a different kind of cryptographic library. In the past crypto
|
32
19
|
libraries were kitchen sinks of little bits and pieces, like ciphers,
|
@@ -50,9 +37,6 @@ curves and the XSalsa20 stream cipher. This means with NaCl you not only get
|
|
50
37
|
a system which is designed to be secure-by-default, you also get one which
|
51
38
|
is extremely fast with comparatively small cryptographic keys.
|
52
39
|
|
53
|
-
For more information on NaCl's goals, see Dan Bernstein's presentation
|
54
|
-
[Blaming the Cryptographic User](http://cr.yp.to/talks/2012.08.08/slides.pdf)
|
55
|
-
|
56
40
|
### Is it any good?
|
57
41
|
|
58
42
|
[Yes.](http://news.ycombinator.com/item?id=3067434)
|
@@ -75,29 +59,19 @@ You can use RbNaCl on platforms libsodium is supported (see below).
|
|
75
59
|
This library aims to support and is [tested against][travis] the following Ruby
|
76
60
|
versions:
|
77
61
|
|
78
|
-
* Ruby 2.2
|
79
|
-
* Ruby 2.3
|
80
|
-
* Ruby 2.4
|
81
|
-
*
|
62
|
+
* Ruby 2.2
|
63
|
+
* Ruby 2.3
|
64
|
+
* Ruby 2.4
|
65
|
+
* Ruby 2.5
|
66
|
+
* JRuby 9.1
|
82
67
|
|
83
68
|
If something doesn't work on one of these versions, it's a bug.
|
84
69
|
|
85
|
-
This library may inadvertently work (or seem to work) on other Ruby versions,
|
86
|
-
however support will only be provided for the versions listed above.
|
87
|
-
|
88
|
-
If you would like this library to support another Ruby version or
|
89
|
-
implementation, you may volunteer to be a maintainer. Being a maintainer
|
90
|
-
entails making sure all tests run and pass on that implementation. When
|
91
|
-
something breaks on your implementation, you will be responsible for providing
|
92
|
-
patches in a timely fashion. If critical issues for a particular implementation
|
93
|
-
exist at the time of a major release, support for that Ruby version may be
|
94
|
-
dropped.
|
95
|
-
|
96
70
|
[travis]: http://travis-ci.org/crypto-rb/rbnacl
|
97
71
|
|
98
72
|
## Installation
|
99
73
|
|
100
|
-
Note: [Windows installation instructions are available](https://github.com/crypto-rb/rbnacl/wiki/
|
74
|
+
Note: [Windows installation instructions are available](https://github.com/crypto-rb/rbnacl/wiki/Installing-libsodium#windows).
|
101
75
|
|
102
76
|
### libsodium
|
103
77
|
|
data/lib/rbnacl.rb
CHANGED
@@ -52,6 +52,9 @@ module RbNaCl
|
|
52
52
|
require "rbnacl/boxes/curve25519xsalsa20poly1305/private_key"
|
53
53
|
require "rbnacl/boxes/curve25519xsalsa20poly1305/public_key"
|
54
54
|
|
55
|
+
# Sealed boxes
|
56
|
+
require "rbnacl/boxes/sealed"
|
57
|
+
|
55
58
|
# Secret Key Encryption (SecretBox): XSalsa20Poly1305
|
56
59
|
require "rbnacl/secret_boxes/xsalsa20poly1305"
|
57
60
|
|
@@ -93,6 +96,7 @@ module RbNaCl
|
|
93
96
|
Box = Boxes::Curve25519XSalsa20Poly1305
|
94
97
|
PrivateKey = Boxes::Curve25519XSalsa20Poly1305::PrivateKey
|
95
98
|
PublicKey = Boxes::Curve25519XSalsa20Poly1305::PublicKey
|
99
|
+
SealedBox = Boxes::Sealed
|
96
100
|
SecretBox = SecretBoxes::XSalsa20Poly1305
|
97
101
|
SigningKey = Signatures::Ed25519::SigningKey
|
98
102
|
VerifyKey = Signatures::Ed25519::VerifyKey
|
@@ -73,7 +73,7 @@ module RbNaCl
|
|
73
73
|
sodium_constant :BOXZEROBYTES
|
74
74
|
sodium_constant :BEFORENMBYTES
|
75
75
|
sodium_constant :PUBLICKEYBYTES
|
76
|
-
sodium_constant :SECRETKEYBYTES, :PRIVATEKEYBYTES
|
76
|
+
sodium_constant :SECRETKEYBYTES, name: :PRIVATEKEYBYTES
|
77
77
|
|
78
78
|
sodium_function :box_curve25519xsalsa20poly1305_beforenm,
|
79
79
|
:crypto_box_curve25519xsalsa20poly1305_beforenm,
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RbNaCl
|
5
|
+
module Boxes
|
6
|
+
# Sealed boxes are designed to anonymously send messages to a recipient
|
7
|
+
# given its public key.
|
8
|
+
#
|
9
|
+
# Only the recipient can decrypt these messages, using its private key.
|
10
|
+
# While the recipient can verify the integrity of the message, it cannot
|
11
|
+
# verify the identity of the sender.
|
12
|
+
#
|
13
|
+
# A message is encrypted using an ephemeral key pair, whose secret part
|
14
|
+
# is destroyed right after the encryption process.
|
15
|
+
#
|
16
|
+
# Without knowing the secret key used for a given message, the sender
|
17
|
+
# cannot decrypt its own message later. And without additional data,
|
18
|
+
# a message cannot be correlated with the identity of its sender.
|
19
|
+
class Sealed
|
20
|
+
extend Sodium
|
21
|
+
|
22
|
+
sodium_type :box
|
23
|
+
sodium_constant :SEALBYTES
|
24
|
+
sodium_primitive :curve25519xsalsa20poly1305
|
25
|
+
|
26
|
+
sodium_function :box_seal,
|
27
|
+
:crypto_box_seal,
|
28
|
+
%i[pointer pointer ulong_long pointer]
|
29
|
+
|
30
|
+
sodium_function :box_seal_open,
|
31
|
+
:crypto_box_seal_open,
|
32
|
+
%i[pointer pointer ulong_long pointer pointer]
|
33
|
+
|
34
|
+
# WARNING: you should strongly prefer the from_private_key/from_public_key class methods.
|
35
|
+
#
|
36
|
+
# Create a new Sealed Box
|
37
|
+
#
|
38
|
+
# Sets up the Box for deriving the shared key and encrypting and
|
39
|
+
# decrypting messages.
|
40
|
+
#
|
41
|
+
# @param public_key [String,RbNaCl::PublicKey] The public key to encrypt to
|
42
|
+
# @param private_key [String,RbNaCl::PrivateKey] The private key to decrypt with
|
43
|
+
#
|
44
|
+
# @raise [RbNaCl::LengthError] on invalid keys
|
45
|
+
#
|
46
|
+
# @return [RbNaCl::SealedBox] The new Box, ready to use
|
47
|
+
def initialize(public_key, private_key = nil)
|
48
|
+
unless private_key.nil?
|
49
|
+
@private_key = private_key.is_a?(PrivateKey) ? private_key : PrivateKey.new(private_key)
|
50
|
+
raise IncorrectPrimitiveError unless @private_key.primitive == primitive
|
51
|
+
|
52
|
+
public_key = @private_key.public_key if public_key.nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
@public_key = public_key.is_a?(PublicKey) ? public_key : PublicKey.new(public_key)
|
56
|
+
raise IncorrectPrimitiveError unless @public_key.primitive == primitive
|
57
|
+
end
|
58
|
+
|
59
|
+
# Create a new Sealed Box for encrypting
|
60
|
+
#
|
61
|
+
# Sets up the Box for encryoption of new messages.
|
62
|
+
#
|
63
|
+
# @param private_key [String,RbNaCl::PrivateKey] The private key to decrypt with
|
64
|
+
#
|
65
|
+
# @raise [RbNaCl::LengthError] on invalid keys
|
66
|
+
#
|
67
|
+
# @return [RbNaCl::SealedBox] The new Box, ready to use
|
68
|
+
def self.from_private_key(private_key)
|
69
|
+
new(nil, private_key)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Create a new Sealed Box for decrypting
|
73
|
+
#
|
74
|
+
# Sets up the Box for decrytoption of new messages.
|
75
|
+
#
|
76
|
+
# @param public_key [String,RbNaCl::PublicKey] The public key to encrypt to
|
77
|
+
#
|
78
|
+
# @raise [RbNaCl::LengthError] on invalid keys
|
79
|
+
#
|
80
|
+
# @return [RbNaCl::SealedBox] The new Box, ready to use
|
81
|
+
def self.from_public_key(public_key)
|
82
|
+
new(public_key, nil)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Encrypts a message
|
86
|
+
#
|
87
|
+
# @param message [String] The message to be encrypted.
|
88
|
+
#
|
89
|
+
# @raise [RbNaCl::CryptoError] If the encrytion fails.
|
90
|
+
#
|
91
|
+
# @return [String] The ciphertext (BINARY encoded)
|
92
|
+
def box(message)
|
93
|
+
# No padding needed.
|
94
|
+
msg = message # variable name to match other RbNaCl code.
|
95
|
+
# ensure enough space in result
|
96
|
+
ct = Util.zeros(msg.bytesize + SEALBYTES)
|
97
|
+
|
98
|
+
success = self.class.box_seal(ct, msg, msg.bytesize, @public_key.to_s)
|
99
|
+
raise CryptoError, "Encryption failed" unless success
|
100
|
+
|
101
|
+
ct
|
102
|
+
end
|
103
|
+
alias encrypt box
|
104
|
+
|
105
|
+
# Decrypts a ciphertext
|
106
|
+
#
|
107
|
+
# @param ciphertext [String] The message to be decrypted.
|
108
|
+
#
|
109
|
+
# @raise [RbNaCl::CryptoError] If no private key is available.
|
110
|
+
# @raise [RbNaCl::CryptoError] If the ciphertext cannot be authenticated.
|
111
|
+
#
|
112
|
+
# @return [String] The decrypted message (BINARY encoded)
|
113
|
+
def open(ciphertext)
|
114
|
+
raise CryptoError, "Decryption failed. No private key." unless @private_key
|
115
|
+
|
116
|
+
ct = ciphertext
|
117
|
+
raise CryptoError, "Decryption failed. Ciphertext failed verification." if ct.bytesize < SEALBYTES
|
118
|
+
|
119
|
+
message = Util.zeros(ct.bytesize - SEALBYTES)
|
120
|
+
|
121
|
+
success = self.class.box_seal_open(message, ct, ct.bytesize, @public_key.to_s, @private_key.to_s)
|
122
|
+
raise CryptoError, "Decryption failed. Ciphertext failed verification." unless success
|
123
|
+
|
124
|
+
message
|
125
|
+
end
|
126
|
+
alias decrypt open
|
127
|
+
|
128
|
+
# The crypto primitive for the box class
|
129
|
+
#
|
130
|
+
# @return [Symbol] The primitive used
|
131
|
+
def primitive
|
132
|
+
self.class.primitive
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/lib/rbnacl/init.rb
CHANGED
@@ -18,18 +18,18 @@ module RbNaCl
|
|
18
18
|
sodium_constant :ALG_ARGON2I13
|
19
19
|
sodium_constant :ALG_ARGON2ID13 if Sodium::Version::ARGON2ID_SUPPORTED
|
20
20
|
|
21
|
-
sodium_constant :SALTBYTES
|
22
|
-
sodium_constant :STRBYTES
|
23
|
-
sodium_constant :OPSLIMIT_INTERACTIVE
|
24
|
-
sodium_constant :MEMLIMIT_INTERACTIVE
|
25
|
-
sodium_constant :OPSLIMIT_MODERATE
|
26
|
-
sodium_constant :MEMLIMIT_MODERATE
|
27
|
-
sodium_constant :OPSLIMIT_SENSITIVE
|
28
|
-
sodium_constant :MEMLIMIT_SENSITIVE
|
29
|
-
sodium_constant :MEMLIMIT_MIN
|
30
|
-
sodium_constant :MEMLIMIT_MAX
|
31
|
-
sodium_constant :OPSLIMIT_MIN
|
32
|
-
sodium_constant :OPSLIMIT_MAX
|
21
|
+
sodium_constant :SALTBYTES, fallback: 16
|
22
|
+
sodium_constant :STRBYTES, fallback: 128
|
23
|
+
sodium_constant :OPSLIMIT_INTERACTIVE, fallback: 4
|
24
|
+
sodium_constant :MEMLIMIT_INTERACTIVE, fallback: 2**25 # (32mb)
|
25
|
+
sodium_constant :OPSLIMIT_MODERATE, fallback: 6
|
26
|
+
sodium_constant :MEMLIMIT_MODERATE, fallback: 2**27 # (128mb)
|
27
|
+
sodium_constant :OPSLIMIT_SENSITIVE, fallback: 8
|
28
|
+
sodium_constant :MEMLIMIT_SENSITIVE, fallback: 2**29 # (512mb)
|
29
|
+
sodium_constant :MEMLIMIT_MIN, fallback: 8192
|
30
|
+
sodium_constant :MEMLIMIT_MAX, fallback: 4_294_967_296
|
31
|
+
sodium_constant :OPSLIMIT_MIN, fallback: 3
|
32
|
+
sodium_constant :OPSLIMIT_MAX, fallback: 10
|
33
33
|
|
34
34
|
ARGON2_MIN_OUTLEN = 16
|
35
35
|
ARGON2_MAX_OUTLEN = 0xFFFFFFFF
|
@@ -10,9 +10,9 @@ module RbNaCl
|
|
10
10
|
sodium_type :sign
|
11
11
|
sodium_primitive :ed25519
|
12
12
|
sodium_constant :SEEDBYTES
|
13
|
-
sodium_constant :PUBLICKEYBYTES, :VERIFYKEYBYTES
|
14
|
-
sodium_constant :SECRETKEYBYTES, :SIGNINGKEYBYTES
|
15
|
-
sodium_constant :BYTES, :SIGNATUREBYTES
|
13
|
+
sodium_constant :PUBLICKEYBYTES, name: :VERIFYKEYBYTES
|
14
|
+
sodium_constant :SECRETKEYBYTES, name: :SIGNINGKEYBYTES
|
15
|
+
sodium_constant :BYTES, name: :SIGNATUREBYTES
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
data/lib/rbnacl/sodium.rb
CHANGED
@@ -8,7 +8,7 @@ module RbNaCl
|
|
8
8
|
module Sodium
|
9
9
|
def self.extended(klass)
|
10
10
|
klass.extend FFI::Library
|
11
|
-
klass.ffi_lib "sodium"
|
11
|
+
klass.ffi_lib ["sodium", "libsodium.so.18", "libsodium.so.23"]
|
12
12
|
end
|
13
13
|
|
14
14
|
def sodium_type(type = nil)
|
@@ -29,14 +29,19 @@ module RbNaCl
|
|
29
29
|
sodium_primitive
|
30
30
|
end
|
31
31
|
|
32
|
-
def sodium_constant(constant, name
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
32
|
+
def sodium_constant(constant, name: constant, fallback: nil)
|
33
|
+
fn_name_components = ["crypto", sodium_type, sodium_primitive, constant.to_s.downcase]
|
34
|
+
fn_name = fn_name_components.compact.join("_")
|
35
|
+
|
36
|
+
begin
|
37
|
+
attach_function fn_name, [], :size_t
|
38
|
+
rescue FFI::NotFoundError
|
39
|
+
raise if fallback.nil?
|
40
|
+
|
41
|
+
define_singleton_method fn_name, -> { fallback }
|
42
|
+
end
|
43
|
+
|
44
|
+
const_set(name, public_send(fn_name))
|
40
45
|
end
|
41
46
|
|
42
47
|
def sodium_function(name, function, arguments)
|
data/lib/rbnacl/version.rb
CHANGED
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
RSpec.describe RbNaCl::SealedBox do
|
5
|
+
let(:alicepk) { vector :alice_public }
|
6
|
+
let(:alicesk) { vector :alice_private }
|
7
|
+
let(:alice_pubkey) { RbNaCl::PublicKey.new(alicepk) }
|
8
|
+
let(:alice_privkey) { RbNaCl::PrivateKey.new(alicesk) }
|
9
|
+
|
10
|
+
context "new" do
|
11
|
+
it "accepts public key strings" do
|
12
|
+
expect do
|
13
|
+
RbNaCl::SealedBox.from_public_key(alicepk)
|
14
|
+
end.to_not raise_error
|
15
|
+
end
|
16
|
+
|
17
|
+
it "accepts public KeyPairs" do
|
18
|
+
expect do
|
19
|
+
RbNaCl::SealedBox.from_public_key(alice_pubkey)
|
20
|
+
end.to_not raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
it "accepts private key strings" do
|
24
|
+
expect do
|
25
|
+
RbNaCl::SealedBox.from_private_key(alicepk)
|
26
|
+
end.to_not raise_error
|
27
|
+
end
|
28
|
+
|
29
|
+
it "accepts private KeyPairs" do
|
30
|
+
expect do
|
31
|
+
RbNaCl::SealedBox.from_private_key(alice_privkey)
|
32
|
+
end.to_not raise_error
|
33
|
+
end
|
34
|
+
|
35
|
+
it "raises TypeError on a nil public key" do
|
36
|
+
expect do
|
37
|
+
RbNaCl::SealedBox.from_public_key(nil)
|
38
|
+
end.to raise_error(TypeError)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "raises RbNaCl::LengthError on an invalid public key" do
|
42
|
+
expect do
|
43
|
+
RbNaCl::SealedBox.from_public_key("hello")
|
44
|
+
end.to raise_error(RbNaCl::LengthError, /Public key was 5 bytes \(Expected 32\)/)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "raises TypeError on a nil private key" do
|
48
|
+
expect do
|
49
|
+
RbNaCl::SealedBox.from_private_key(nil)
|
50
|
+
end.to raise_error(TypeError)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "raises RbNaCl::LengthError on an invalid private key" do
|
54
|
+
expect do
|
55
|
+
RbNaCl::SealedBox.from_private_key("hello")
|
56
|
+
end.to raise_error(RbNaCl::LengthError, /Private key was 5 bytes \(Expected 32\)/)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
include_examples "sealed_box" do
|
61
|
+
let(:box) { RbNaCl::SealedBox.new(alicepk, alicesk) }
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
RSpec.describe RbNaCl::Sodium do
|
2
|
+
subject(:sodium_class) do
|
3
|
+
class SodiumExtendedClass
|
4
|
+
extend RbNaCl::Sodium
|
5
|
+
|
6
|
+
sodium_type :auth
|
7
|
+
sodium_primitive :hmacsha512
|
8
|
+
# sodium_constant :BYTES
|
9
|
+
# sodium_constant :KEYBYTES
|
10
|
+
end
|
11
|
+
SodiumExtendedClass
|
12
|
+
end
|
13
|
+
|
14
|
+
context ".sodium_constant" do
|
15
|
+
it "retrieves the libsodium constant" do
|
16
|
+
sodium_class.sodium_constant :BYTES
|
17
|
+
expect(sodium_class::BYTES).to eq(64)
|
18
|
+
end
|
19
|
+
|
20
|
+
context "with alternate constant name" do
|
21
|
+
it "sets the alternate constant name" do
|
22
|
+
sodium_class.sodium_constant :BYTES, name: :COOL_BYTES
|
23
|
+
expect(sodium_class::COOL_BYTES).to eq(64)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when libsodium does not define the constant" do
|
28
|
+
it "raises an exception" do
|
29
|
+
expect do
|
30
|
+
sodium_class.sodium_constant :MIN_DANCING_PARTNERS
|
31
|
+
end.to raise_error(FFI::NotFoundError)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with fallback" do
|
36
|
+
context "when libsodium defines the constant" do
|
37
|
+
it "return the libsodium value" do
|
38
|
+
sodium_class.sodium_constant :BYTES, fallback: 888
|
39
|
+
expect(sodium_class::BYTES).to eq(64)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when libsodium does not define the constant" do
|
44
|
+
it "uses the fallback" do
|
45
|
+
sodium_class.sodium_constant :MAX_PANDAS, fallback: 24
|
46
|
+
expect(sodium_class::MAX_PANDAS).to eq(24)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
RSpec.shared_examples "sealed_box" do
|
5
|
+
let(:message) { vector :box_message }
|
6
|
+
let(:ciphertext) { vector :box_ciphertext }
|
7
|
+
let(:corrupt_ciphertext) { ciphertext[80] = " " } # picked at random by fair diceroll
|
8
|
+
|
9
|
+
context "box" do
|
10
|
+
it "roundtrips" do
|
11
|
+
ciphertext = box.box(message)
|
12
|
+
expect(box.open(ciphertext)).to eq message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "open" do
|
17
|
+
it "raises on a truncated message to decrypt" do
|
18
|
+
expect do
|
19
|
+
box.open(ciphertext[0, 64])
|
20
|
+
end.to raise_error(RbNaCl::CryptoError, /Decryption failed. Ciphertext failed verification./)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "raises on a corrupt ciphertext" do
|
24
|
+
expect do
|
25
|
+
box.open(corrupt_ciphertext)
|
26
|
+
end.to raise_error(RbNaCl::CryptoError, /Decryption failed. Ciphertext failed verification./)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbnacl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.
|
4
|
+
version: 6.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Arcieri
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-01-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb
|
74
74
|
- lib/rbnacl/boxes/curve25519xsalsa20poly1305/private_key.rb
|
75
75
|
- lib/rbnacl/boxes/curve25519xsalsa20poly1305/public_key.rb
|
76
|
+
- lib/rbnacl/boxes/sealed.rb
|
76
77
|
- lib/rbnacl/group_elements/curve25519.rb
|
77
78
|
- lib/rbnacl/hash.rb
|
78
79
|
- lib/rbnacl/hash/blake2b.rb
|
@@ -108,6 +109,7 @@ files:
|
|
108
109
|
- spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb
|
109
110
|
- spec/rbnacl/boxes/curve25519xsalsa20poly1305/public_key_spec.rb
|
110
111
|
- spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb
|
112
|
+
- spec/rbnacl/boxes/sealed_spec.rb
|
111
113
|
- spec/rbnacl/group_element_spec.rb
|
112
114
|
- spec/rbnacl/hash/blake2b_spec.rb
|
113
115
|
- spec/rbnacl/hash_spec.rb
|
@@ -121,12 +123,14 @@ files:
|
|
121
123
|
- spec/rbnacl/signatures/ed25519/signing_key_spec.rb
|
122
124
|
- spec/rbnacl/signatures/ed25519/verify_key_spec.rb
|
123
125
|
- spec/rbnacl/simple_box_spec.rb
|
126
|
+
- spec/rbnacl/sodium_spec.rb
|
124
127
|
- spec/rbnacl/util_spec.rb
|
125
128
|
- spec/shared/aead.rb
|
126
129
|
- spec/shared/authenticator.rb
|
127
130
|
- spec/shared/box.rb
|
128
131
|
- spec/shared/hmac.rb
|
129
132
|
- spec/shared/key_equality.rb
|
133
|
+
- spec/shared/sealed_box.rb
|
130
134
|
- spec/shared/serializable.rb
|
131
135
|
- spec/spec_helper.rb
|
132
136
|
- tasks/rspec.rake
|
@@ -163,6 +167,7 @@ test_files:
|
|
163
167
|
- spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb
|
164
168
|
- spec/rbnacl/boxes/curve25519xsalsa20poly1305/public_key_spec.rb
|
165
169
|
- spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb
|
170
|
+
- spec/rbnacl/boxes/sealed_spec.rb
|
166
171
|
- spec/rbnacl/group_element_spec.rb
|
167
172
|
- spec/rbnacl/hash/blake2b_spec.rb
|
168
173
|
- spec/rbnacl/hash_spec.rb
|
@@ -176,11 +181,13 @@ test_files:
|
|
176
181
|
- spec/rbnacl/signatures/ed25519/signing_key_spec.rb
|
177
182
|
- spec/rbnacl/signatures/ed25519/verify_key_spec.rb
|
178
183
|
- spec/rbnacl/simple_box_spec.rb
|
184
|
+
- spec/rbnacl/sodium_spec.rb
|
179
185
|
- spec/rbnacl/util_spec.rb
|
180
186
|
- spec/shared/aead.rb
|
181
187
|
- spec/shared/authenticator.rb
|
182
188
|
- spec/shared/box.rb
|
183
189
|
- spec/shared/hmac.rb
|
184
190
|
- spec/shared/key_equality.rb
|
191
|
+
- spec/shared/sealed_box.rb
|
185
192
|
- spec/shared/serializable.rb
|
186
193
|
- spec/spec_helper.rb
|