rbnacl 1.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/.coveralls.yml +1 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +4 -0
  4. data/.travis.yml +21 -0
  5. data/.yardopts +1 -0
  6. data/CHANGES.md +4 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE.txt +23 -0
  9. data/README.md +179 -0
  10. data/Rakefile +5 -0
  11. data/images/dragons.png +0 -0
  12. data/images/ed25519.png +0 -0
  13. data/images/logo.png +0 -0
  14. data/lib/rbnacl.rb +46 -0
  15. data/lib/rbnacl/auth.rb +78 -0
  16. data/lib/rbnacl/auth/one_time.rb +38 -0
  17. data/lib/rbnacl/box.rb +141 -0
  18. data/lib/rbnacl/encoder.rb +44 -0
  19. data/lib/rbnacl/encoders/base32.rb +33 -0
  20. data/lib/rbnacl/encoders/base64.rb +30 -0
  21. data/lib/rbnacl/encoders/hex.rb +30 -0
  22. data/lib/rbnacl/encoders/raw.rb +12 -0
  23. data/lib/rbnacl/hash.rb +48 -0
  24. data/lib/rbnacl/hmac/sha256.rb +32 -0
  25. data/lib/rbnacl/hmac/sha512256.rb +35 -0
  26. data/lib/rbnacl/keys/key_comparator.rb +59 -0
  27. data/lib/rbnacl/keys/private_key.rb +62 -0
  28. data/lib/rbnacl/keys/public_key.rb +38 -0
  29. data/lib/rbnacl/keys/signing_key.rb +74 -0
  30. data/lib/rbnacl/keys/verify_key.rb +76 -0
  31. data/lib/rbnacl/nacl.rb +132 -0
  32. data/lib/rbnacl/point.rb +67 -0
  33. data/lib/rbnacl/rake_tasks.rb +56 -0
  34. data/lib/rbnacl/random.rb +19 -0
  35. data/lib/rbnacl/random_nonce_box.rb +109 -0
  36. data/lib/rbnacl/secret_box.rb +86 -0
  37. data/lib/rbnacl/self_test.rb +118 -0
  38. data/lib/rbnacl/serializable.rb +23 -0
  39. data/lib/rbnacl/test_vectors.rb +69 -0
  40. data/lib/rbnacl/util.rb +137 -0
  41. data/lib/rbnacl/version.rb +5 -0
  42. data/rbnacl.gemspec +28 -0
  43. data/rbnacl.gpg +30 -0
  44. data/spec/rbnacl/auth/one_time_spec.rb +8 -0
  45. data/spec/rbnacl/box_spec.rb +42 -0
  46. data/spec/rbnacl/encoder_spec.rb +14 -0
  47. data/spec/rbnacl/encoders/base32_spec.rb +16 -0
  48. data/spec/rbnacl/encoders/base64_spec.rb +15 -0
  49. data/spec/rbnacl/encoders/hex_spec.rb +15 -0
  50. data/spec/rbnacl/hash_spec.rb +52 -0
  51. data/spec/rbnacl/hmac/sha256_spec.rb +8 -0
  52. data/spec/rbnacl/hmac/sha512256_spec.rb +8 -0
  53. data/spec/rbnacl/keys/private_key_spec.rb +68 -0
  54. data/spec/rbnacl/keys/public_key_spec.rb +45 -0
  55. data/spec/rbnacl/keys/signing_key_spec.rb +40 -0
  56. data/spec/rbnacl/keys/verify_key_spec.rb +51 -0
  57. data/spec/rbnacl/point_spec.rb +29 -0
  58. data/spec/rbnacl/random_nonce_box_spec.rb +78 -0
  59. data/spec/rbnacl/random_spec.rb +9 -0
  60. data/spec/rbnacl/secret_box_spec.rb +24 -0
  61. data/spec/rbnacl/util_spec.rb +119 -0
  62. data/spec/shared/authenticator.rb +114 -0
  63. data/spec/shared/box.rb +51 -0
  64. data/spec/shared/key_equality.rb +26 -0
  65. data/spec/spec_helper.rb +14 -0
  66. data/tasks/ci.rake +11 -0
  67. data/tasks/rspec.rake +7 -0
  68. metadata +187 -0
@@ -0,0 +1 @@
1
+ service-name: travis-pro
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ libsodium
19
+ libsodium-*.tar.gz
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --format documentation
3
+ --backtrace
4
+ --default_path spec
@@ -0,0 +1,21 @@
1
+ script: "LD_LIBRARY_PATH=lib bundle exec rake ci"
2
+
3
+ rvm:
4
+ - 1.8.7
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - ree
8
+ - ruby-head
9
+ - jruby-18mode
10
+ - jruby-19mode
11
+ - jruby-head
12
+ - rbx-18mode
13
+ - rbx-19mode
14
+
15
+ matrix:
16
+ allow_failures:
17
+ - rvm: ruby-head
18
+ - rvm: jruby-head
19
+
20
+ notifications:
21
+ irc: "irc.freenode.org#cryptosphere"
@@ -0,0 +1 @@
1
+ --markup markdown --no-private lib/**/*.rb - README.md LICENSE.txt
@@ -0,0 +1,4 @@
1
+ HEAD
2
+ ----
3
+
4
+ Unreleased!
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rbnacl.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'base32'
8
+ gem 'coveralls', :require => false
9
+ end
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2012 Tony Arcieri
2
+ Copyright (c) 2013 Jonathan Stott
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,179 @@
1
+ ![RbNaCl](https://raw.github.com/cryptosphere/rbnacl/master/images/logo.png)
2
+ ======
3
+ [![Build Status](https://travis-ci.org/cryptosphere/rbnacl.png?branch=master)](https://travis-ci.org/cryptosphere/rbnacl)
4
+ [![Code Climate](https://codeclimate.com/github/cryptosphere/rbnacl.png)](https://codeclimate.com/github/cryptosphere/rbnacl)
5
+ [![Coverage Status](https://coveralls.io/repos/cryptosphere/rbnacl/badge.png?branch=master)](https://coveralls.io/r/cryptosphere/rbnacl)
6
+
7
+ A Ruby binding to the state-of-the-art [Networking and Cryptography][nacl]
8
+ library by Daniel J. Bernstein. This is **NOT** Google Native Client. This
9
+ is a crypto library.
10
+
11
+ On a completely unrelated topic, RbNaCl is also the empirical formula for
12
+ Rubidium Sodium Chloride.
13
+
14
+ Need help with RbNaCl? Join the [RbNaCl Google Group][group]
15
+
16
+ [nacl]: http://nacl.cr.yp.to/
17
+ [group]: http://groups.google.com/group/rbnacl
18
+
19
+ ## Why NaCl?
20
+
21
+ NaCl is a different kind of cryptographic library. In the past crypto
22
+ libraries were kitchen sinks of little bits and pieces, like ciphers,
23
+ MACs, signature algorithms, and hash functions. To accomplish anything
24
+ you had to make a lot of decisions about which specific pieces to use,
25
+ and if any of your decisions were wrong, the result was an insecure
26
+ system. The choices are also not easy: EAX? GCM? CCM? AES-CTR? CMAC?
27
+ OMAC1? AEAD? NIST? CBC? CFB? CTR? ECB? OMGWTFBBQ!
28
+
29
+ NaCl puts cryptography on Rails! Instead of making you choose which
30
+ cryptographic primitives to use, NaCl provides convention over configuration
31
+ in the form of expertly-assembled high-level cryptographic APIs that ensure
32
+ not only the confidentiality of your data, but also detect tampering.
33
+ These high-level, easy-to-use APIs are designed to be hard to attack by
34
+ default in ways primitives exposed by libraries like OpenSSL are not.
35
+
36
+ This approach makes NaCl a lot closer to a system like GPG than it is
37
+ to the cryptographic primitive APIs in a library like OpenSSL. In addition,
38
+ NaCl also uses state-of-the-art encryption, including Curve25519 elliptic
39
+ curves and the XSalsa20 stream cipher. This means with NaCl you not only get
40
+ a system which is designed to be secure-by-default, you also get one which
41
+ is extremely fast with comparatively small cryptographic keys.
42
+
43
+ For more information on NaCl's goals, see Dan Bernstein's presentation
44
+ [Blaming the Cryptographic User](http://cr.yp.to/talks/2012.08.08/slides.pdf)
45
+
46
+ ## Supported platforms
47
+
48
+ You can use RbNaCl anywhere you can get libsodium installed (see below).
49
+ RbNaCl is continuously integration tested on the following Ruby VMs:
50
+
51
+ * MRI 1.8 / REE
52
+ * MRI 1.9 (YARV)
53
+ * JRuby 1.7 (in both 1.8/1.9 mode)
54
+ * Rubinius HEAD (in both 1.8/1.9 mode)
55
+
56
+ In theory Windows should be supported, although there are not yet any
57
+ reports of successful Windows users.
58
+
59
+ ## Installation
60
+
61
+ ### libsodium
62
+
63
+ RbNaCl is implemented as a Ruby FFI binding, which is designed to bind to
64
+ shared libraries. Unfortunately NaCl does not presently ship a shared library,
65
+ so RbNaCl cannot take advantage of it via FFI. RbNaCl will support usage with
66
+ the upstream NaCl once it is able to compile a shared library.
67
+
68
+ For now, to use RbNaCl, you will need to install libsodium, a portable version
69
+ of NaCl based upon the reference C code. Please see the libsodium project
70
+ for information regarding installation:
71
+
72
+ https://github.com/jedisct1/libsodium
73
+
74
+ #### OS X
75
+
76
+ Unfortunately libsodium is not in homebrew proper yet (I would strongly
77
+ encourage you to [ask for libsodium's inclusion in homebrew][homebrew]),
78
+ however you can use homebrew's "tap" feature for the time being to
79
+ install libsodium:
80
+
81
+ ```
82
+ brew tap qmx/homebrew-libsodium
83
+ brew install libsodium
84
+ ```
85
+
86
+ [homebrew]: https://github.com/mxcl/homebrew/pull/17275
87
+
88
+ ### RbNaCl gem
89
+
90
+ Once you have libsodium installed, add this line to your application's Gemfile:
91
+
92
+ gem 'rbnacl'
93
+
94
+ And then execute:
95
+
96
+ $ bundle
97
+
98
+ Or install it yourself as:
99
+
100
+ $ gem install rbnacl
101
+
102
+ ## Documentation
103
+
104
+ RbNaCl's documentation can be found [in the Wiki][wiki]. The following features
105
+ are supported:
106
+
107
+ * [Secret-key Encryption][secretkey]: authenticated symmetric encryption using a
108
+ single key shared among parties
109
+ * [Public-key Encryption][publickey]: securely send messages to a given public
110
+ key which can only be decrypted by a secret key
111
+ * [Digital Signatures][signatures]: sign messages with a private key which can
112
+ be verified by a public one
113
+ * [Authenticators][macs]: create codes which can be used to check the
114
+ authenticity of messages
115
+ * [Hash Functions][hashes]: compute a secure, fixed-length code from a message
116
+ which does not reveal the contents of the message
117
+
118
+ Additional power-user features are available. Please see the Wiki for further
119
+ information.
120
+
121
+ [wiki]: https://github.com/cryptosphere/rbnacl/wiki
122
+ [secretkey]: https://github.com/cryptosphere/rbnacl/wiki/Secret-Key-Encryption
123
+ [publickey]: https://github.com/cryptosphere/rbnacl/wiki/Public-Key-Encryption
124
+ [signatures]: https://github.com/cryptosphere/rbnacl/wiki/Digital-Signatures
125
+ [macs]: https://github.com/cryptosphere/rbnacl/wiki/Authenticators
126
+ [hashes]: https://github.com/cryptosphere/rbnacl/wiki/Hash-Functions
127
+
128
+ ## Security Notes
129
+
130
+ NaCl itself has been expertly crafted to avoid a whole range of
131
+ side-channel attacks, however the RbNaCl code itself has not been
132
+ written with the same degree of expertise. While the code is
133
+ straightforward it should be considered experimental until audited
134
+ by professional cryptographers.
135
+
136
+ That said, it's probably still a million times better than OpenSSL...
137
+
138
+ ## Reporting Security Problems
139
+
140
+ If you have discovered a bug in RbNaCl of a sensitive nature, i.e.
141
+ one which can compromise the security of RbNaCl users, you can
142
+ report it securely by sending a GPG encrypted message. Please use
143
+ the following key:
144
+
145
+ https://raw.github.com/cryptosphere/rbnacl/master/rbnacl.gpg
146
+
147
+ The key fingerprint is (or should be):
148
+
149
+ `190E 42D6 8327 A515 BFDF AAE0 B210 269D BB2D 8787`
150
+
151
+ ## Learn More
152
+
153
+ While NaCl has designed to be easier-than-usual to use for a crypto
154
+ library, cryptography is an incredibly difficult subject and it's
155
+ always helpful to know as much as you can about it before applying
156
+ it to a particular use case. That said, the creator of NaCl, Dan
157
+ Bernstein, has published a number of papers about NaCl. If you are
158
+ interested in learning more about how NaCl works, it's recommended
159
+ that you read them:
160
+
161
+ * [Cryptography in NaCl](http://cr.yp.to/highspeed/naclcrypto-20090310.pdf)
162
+ * [Curve25519: new Diffie-Hellman speed records](http://cr.yp.to/ecdh/curve25519-20060209.pdf)
163
+ * [Ed25519: High-speed high-security signatures](http://ed25519.cr.yp.to/ed25519-20110926.pdf)
164
+
165
+ Have a general interest in cryptography? Check out the free course
166
+ Coursera offers from Stanford University Professor Dan Boneh:
167
+
168
+ [http://crypto-class.org](http://crypto-class.org)
169
+
170
+ ## Contributing
171
+
172
+ * Fork this repository on Github
173
+ * Make your changes and send a pull request
174
+ * If your changes look good, we'll merge 'em
175
+
176
+ ## License
177
+
178
+ Copyright (c) 2013 Tony Arcieri, Jonathan Stott.
179
+ Distributed under the MIT License. See LICENSE.txt for further details.
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ Dir[File.expand_path("../tasks/**/*.rake", __FILE__)].each { |task| load task }
3
+ require File.expand_path("../lib/rbnacl/rake_tasks", __FILE__)
4
+
5
+ task :default => :spec
Binary file
Binary file
Binary file
@@ -0,0 +1,46 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ # Oh no, something went wrong!
4
+ #
5
+ # This indicates a failure in the operation of a cryptographic primitive such
6
+ # as authentication failing on an attempt to decrypt a ciphertext. Classes
7
+ # in the library may define more specific subclasses.
8
+ class CryptoError < StandardError; end
9
+
10
+ # Something, probably a key, is the wrong length
11
+ #
12
+ # This indicates some argument with an expected length was not that length.
13
+ # Since this is probably a cryptographic key, you should check that!
14
+ class LengthError < ArgumentError; end
15
+ end
16
+
17
+ # TIMTOWTDI!
18
+ RbNaCl = Crypto
19
+
20
+ require "rbnacl/nacl"
21
+ require "rbnacl/version"
22
+ require "rbnacl/serializable"
23
+ require "rbnacl/keys/key_comparator"
24
+ require "rbnacl/keys/private_key"
25
+ require "rbnacl/keys/public_key"
26
+ require "rbnacl/keys/signing_key"
27
+ require "rbnacl/keys/verify_key"
28
+ require "rbnacl/box"
29
+ require "rbnacl/secret_box"
30
+ require "rbnacl/hash"
31
+ require "rbnacl/util"
32
+ require "rbnacl/auth"
33
+ require "rbnacl/hmac/sha512256"
34
+ require "rbnacl/hmac/sha256"
35
+ require "rbnacl/auth/one_time"
36
+ require "rbnacl/random"
37
+ require "rbnacl/encoder"
38
+ require "rbnacl/encoders/base64"
39
+ require "rbnacl/encoders/hex"
40
+ require "rbnacl/encoders/raw"
41
+ require "rbnacl/point"
42
+ require "rbnacl/random_nonce_box"
43
+ require "rbnacl/test_vectors"
44
+
45
+ # Perform self test on load
46
+ require "rbnacl/self_test"
@@ -0,0 +1,78 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ # Secret Key Authenticators
4
+ #
5
+ # These provide a means of verifying the integrity of a message, but only
6
+ # with the knowledge of a shared key. This can be a preshared key, or one
7
+ # that is derived through some cryptographic protocol.
8
+ class Auth
9
+ # Number of bytes in a valid key
10
+ KEYBYTES = 0
11
+
12
+ # Number of bytes in a valid authenticator
13
+ BYTES = 0
14
+
15
+ attr_reader :key
16
+ private :key
17
+
18
+ # A new authenticator, ready for auth and verification
19
+ #
20
+ # @param [#to_str] key the key used for authenticators, 32 bytes.
21
+ # @param [#to_sym] encoding decode key from this format (default raw)
22
+ def initialize(key, encoding = :raw)
23
+ @key = Encoder[encoding].decode(key)
24
+ Util.check_length(@key, self.class::KEYBYTES, "#{self.class} key")
25
+ end
26
+
27
+ # Compute authenticator for message
28
+ #
29
+ # @param [#to_str] key the key used for the authenticator
30
+ # @param [#to_str] message message to construct an authenticator for
31
+ #
32
+ # @return [String] The authenticator, as raw bytes
33
+ def self.auth(key, message)
34
+ new(key).auth(message)
35
+ end
36
+
37
+ # Verifies the given authenticator with the message.
38
+ #
39
+ # @param [#to_str] key the key used for the authenticator
40
+ # @param [#to_str] message the message to be authenticated
41
+ # @param [#to_str] authenticator to be checked
42
+ #
43
+ # @return [Boolean] Was it valid?
44
+ def self.verify(key, message, authenticator)
45
+ new(key).verify(message, authenticator)
46
+ end
47
+
48
+ # Compute authenticator for message
49
+ #
50
+ # @param [#to_str] message the message to authenticate
51
+ # @param [#to_sym] authenticator_encoding format of the authenticator (default raw)
52
+ #
53
+ # @return [String] The authenticator in the requested encoding (default raw)
54
+ def auth(message, authenticator_encoding = :raw)
55
+ authenticator = Util.zeros(self.class::BYTES)
56
+ message = message.to_str
57
+ compute_authenticator(message, authenticator)
58
+ Encoder[authenticator_encoding].encode(authenticator)
59
+ end
60
+
61
+ # Verifies the given authenticator with the message.
62
+ #
63
+ # @param [#to_str] authenticator to be checked
64
+ # @param [#to_str] message the message to be authenticated
65
+ # @param [#to_sym] authenticator_encoding format of the authenticator (default raw)
66
+ #
67
+ # @return [Boolean] Was it valid?
68
+ def verify(message, authenticator, authenticator_encoding = :raw)
69
+ auth = Encoder[authenticator_encoding].decode(authenticator)
70
+ return false unless auth.bytesize == self.class::BYTES
71
+ verify_message(message, auth)
72
+ end
73
+
74
+ private
75
+ def compute_authenticator(message, authenticator); raise NotImplementedError; end
76
+ def verify_message(message, authenticator); raise NotImplementedError; end
77
+ end
78
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ class Auth
4
+ # Computes an authenticator using poly1305
5
+ #
6
+ # The authenticator can be used at a later time to verify the provenence of
7
+ # the message by recomputing the tag over the message and then comparing it to
8
+ # the provided authenticator. The class provides methods for generating
9
+ # signatures and also has a constant-time implementation for checking them.
10
+ #
11
+ # As the name suggests, this is a **ONE TIME** authenticator. Computing an
12
+ # authenticator for two messages using the same key probably gives an
13
+ # attacker enough information to forge further authenticators for the same
14
+ # key.
15
+ #
16
+ # This is a secret key authenticator, i.e. anyone who can verify signatures
17
+ # can also create them.
18
+ #
19
+ # @see http://nacl.cr.yp.to/onetimeauth.html
20
+ class OneTime < self
21
+ # Number of bytes in a valid key
22
+ KEYBYTES = NaCl::ONETIME_KEYBYTES
23
+
24
+ # Number of bytes in a valid authenticator
25
+ BYTES = NaCl::ONETIME_BYTES
26
+
27
+ private
28
+ def compute_authenticator(message, authenticator)
29
+ NaCl.crypto_auth_onetime(authenticator, message, message.bytesize, key)
30
+ end
31
+
32
+ def verify_message(message, authenticator)
33
+ NaCl.crypto_auth_onetime_verify(authenticator, message, message.bytesize, key)
34
+ end
35
+
36
+ end
37
+ end
38
+ end