jose 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d815c65355a2d467ff34ae0ac101edfc95cf0f13
4
- data.tar.gz: 6dce3b24964e2cc44d53d5626fd93c6f532b4606
3
+ metadata.gz: 7376ae594edf0f6ec851ffe557de7d6f0f1680cd
4
+ data.tar.gz: 9a65bee349e4419c92c7b1bd01e08008ae82a2b3
5
5
  SHA512:
6
- metadata.gz: a8fbbbd04314ba7b7c3a27d3ff5954ecc239648fc55e08fde8243c8e5abed253e9a4de65bb4afcb306a7f972abb446b6e4846298ca7b7c411fd9b6c5227887f0
7
- data.tar.gz: ff01ce855127f8a3a93c7437e5b961ec97134bfa76845f5127c584c976a978c80246cd8275c716807c249c7f1945df7a98ef5f009d8642a1b55f1a2e0a69394b
6
+ metadata.gz: ee8d43fd9d51f20753b853d1da36e8d2dc0cb8f725f20b88f825f5c8f369cb365027654f97bd0ac06f3865afc3119a5b9bbffb0d58e8353ae775b00221138c6b
7
+ data.tar.gz: 8700bb7d9c63aae53281e3619067d503b35d4ca6691bf7e1782d33709e4c14122a23598dc474e49601d9575fd09d6394c246723a42dca6a0a7758fad90aae39d
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.3
1
+ 2.3.0
data/.travis.yml CHANGED
@@ -1,4 +1,13 @@
1
1
  language: ruby
2
+
3
+ sudo: required
4
+ dist: trusty
5
+
2
6
  rvm:
3
- - 2.2.3
4
- before_install: gem install bundler -v 1.10.6
7
+ - 2.3.0
8
+
9
+ notifications:
10
+ email: false
11
+
12
+ before_install:
13
+ - "gem install bundler -v 1.11.2"
data/CHANGELOG.md ADDED
@@ -0,0 +1,69 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 (2016-02-25)
4
+
5
+ * Enhancements
6
+ * Add `JOSE.__crypto_fallback__` which can be set directly or with the `JOSE_CRYPTO_FALLBACK` environment variable. EdDSA and EdDH algorithms not natively supported are disabled by default.
7
+ * Support [OKP](https://tools.ietf.org/html/draft-ietf-jose-cfrg-curves) key type with the following curves:
8
+ * `Ed25519` (external [RbNaCl](https://github.com/cryptosphere/rbnacl) or fallback supported)
9
+ * `Ed25519ph` (external [RbNaCl](https://github.com/cryptosphere/rbnacl) or fallback supported)
10
+ * `X25519` (external [RbNaCl](https://github.com/cryptosphere/rbnacl) or fallback supported)
11
+ * `Ed448` (no external, but fallback supported)
12
+ * `Ed448ph` (no external, but fallback supported)
13
+ * `X448` (no external, but fallback supported)
14
+ * Support [SHA-3](https://en.wikipedia.org/wiki/SHA-3) functions for use with `Ed448` and `Ed448ph`.
15
+ * Add `JOSE::JWK#shared_secret` for computing the shared secret between two `EC` or `OKP` keys.
16
+
17
+ ## 0.1.0 (2015-11-24)
18
+
19
+ * Initial Release
20
+
21
+ * Algorithm Support
22
+ * JSON Web Encryption (JWE) [RFC 7516](https://tools.ietf.org/html/rfc7516)
23
+ * `"alg"` [RFC 7518 Section 4](https://tools.ietf.org/html/rfc7518#section-4)
24
+ * `RSA1_5`
25
+ * `RSA-OAEP`
26
+ * `RSA-OAEP-256`
27
+ * `A128KW`
28
+ * `A192KW`
29
+ * `A256KW`
30
+ * `dir`
31
+ * `ECDH-ES`
32
+ * `ECDH-ES+A128KW`
33
+ * `ECDH-ES+A192KW`
34
+ * `ECDH-ES+A256KW`
35
+ * `A128GCMKW`
36
+ * `A192GCMKW`
37
+ * `A256GCMKW`
38
+ * `PBES2-HS256+A128KW`
39
+ * `PBES2-HS384+A192KW`
40
+ * `PBES2-HS512+A256KW`
41
+ * `"enc"` [RFC 7518 Section 5](https://tools.ietf.org/html/rfc7518#section-5)
42
+ * `A128CBC-HS256`
43
+ * `A192CBC-HS384`
44
+ * `A256CBC-HS512`
45
+ * `A128GCM`
46
+ * `A192GCM`
47
+ * `A256GCM`
48
+ * `"zip"` [RFC 7518 Section 7.3](https://tools.ietf.org/html/rfc7518#section-7.3)
49
+ * `DEF`
50
+ * JSON Web Key (JWK) [RFC 7517](https://tools.ietf.org/html/rfc7517)
51
+ * `"alg"` [RFC 7518 Section 6](https://tools.ietf.org/html/rfc7518#section-6)
52
+ * `EC`
53
+ * `RSA`
54
+ * `oct`
55
+ * JSON Web Signature (JWS) [RFC 7515](https://tools.ietf.org/html/rfc7515)
56
+ * `"alg"` [RFC 7518 Section 3](https://tools.ietf.org/html/rfc7518#section-3)
57
+ * `HS256`
58
+ * `HS384`
59
+ * `HS512`
60
+ * `RS256`
61
+ * `RS384`
62
+ * `RS512`
63
+ * `ES256`
64
+ * `ES384`
65
+ * `ES512`
66
+ * `PS256`
67
+ * `PS384`
68
+ * `PS512`
69
+ * `none`
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # JOSE
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/jose`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![Build Status](https://travis-ci.org/potatosalad/ruby-jose.png?branch=master)](https://travis-ci.org/potatosalad/ruby-jose)
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ JSON Object Signing and Encryption (JOSE) for Ruby.
6
+
7
+ Heavily based on [erlang-jose](https://github.com/potatosalad/erlang-jose).
6
8
 
7
9
  ## Installation
8
10
 
@@ -32,7 +34,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
32
34
 
33
35
  ## Contributing
34
36
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/jose. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
37
+ Bug reports and pull requests are welcome on GitHub at https://github.com/potatosalad/ruby-jose. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
36
38
 
37
39
 
38
40
  ## License
data/jose.gemspec CHANGED
@@ -29,8 +29,9 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.add_dependency "hamster"
31
31
 
32
- spec.add_development_dependency "bundler", "~> 1.10"
33
- spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "bundler", "~> 1.11"
33
+ spec.add_development_dependency "rake", "~> 10.5"
34
34
  spec.add_development_dependency "minitest"
35
35
  spec.add_development_dependency "json"
36
+ spec.add_development_dependency "rbnacl-libsodium"
36
37
  end
data/lib/jose.rb CHANGED
@@ -4,21 +4,48 @@ require 'base64'
4
4
  require 'hamster/hash'
5
5
  require 'json'
6
6
  require 'openssl'
7
+ require 'thread'
7
8
 
8
9
  module JOSE
9
10
  class Map < Hamster::Hash; end
10
11
  end
11
12
 
12
- require 'jose/jwa'
13
- require 'jose/jwe'
14
- require 'jose/jwk'
15
- require 'jose/jws'
16
- require 'jose/jwt'
17
-
18
13
  module JOSE
19
14
 
20
15
  extend self
21
16
 
17
+ MUTEX = Mutex.new
18
+
19
+ @__crypto_fallback__ = ENV['JOSE_CRYPTO_FALLBACK'] ? true : false
20
+
21
+ def __crypto_fallback__
22
+ return @__crypto_fallback__
23
+ end
24
+
25
+ def __crypto_fallback__=(boolean)
26
+ boolean = !!boolean
27
+ MUTEX.synchronize {
28
+ @__crypto_fallback__ = boolean
29
+ __config_change__
30
+ }
31
+ end
32
+
33
+ def __curve25519_module__
34
+ return JOSE::JWA::Curve25519.__implementation__
35
+ end
36
+
37
+ def __curve25519_module__=(m)
38
+ JOSE::JWA::Curve25519.__implementation__ = m
39
+ end
40
+
41
+ def __curve448_module__
42
+ return JOSE::JWA::Curve448.__implementation__
43
+ end
44
+
45
+ def __curve448_module__=(m)
46
+ JOSE::JWA::Curve448.__implementation__ = m
47
+ end
48
+
22
49
  def decode(binary)
23
50
  return JSON.load(binary)
24
51
  end
@@ -43,6 +70,11 @@ module JOSE
43
70
 
44
71
  private
45
72
 
73
+ def __config_change__
74
+ JOSE::JWA::Curve25519.__config_change__
75
+ JOSE::JWA::Curve448.__config_change__
76
+ end
77
+
46
78
  def sort_maps(term)
47
79
  case term
48
80
  when Hash, JOSE::Map
@@ -59,3 +91,9 @@ private
59
91
  end
60
92
 
61
93
  end
94
+
95
+ require 'jose/jwa'
96
+ require 'jose/jwe'
97
+ require 'jose/jwk'
98
+ require 'jose/jws'
99
+ require 'jose/jwt'
data/lib/jose/jwa.rb CHANGED
@@ -3,6 +3,9 @@ module JOSE
3
3
 
4
4
  extend self
5
5
 
6
+ UCHAR_PACK = 'C*'.freeze
7
+ ZERO_PAD = [0].pack('C').force_encoding('BINARY').freeze
8
+
6
9
  def constant_time_compare(a, b)
7
10
  return false if a.empty? || b.empty? || a.bytesize != b.bytesize
8
11
  l = a.unpack "C#{a.bytesize}"
@@ -12,10 +15,30 @@ module JOSE
12
15
  return res == 0
13
16
  end
14
17
 
18
+ def exor(a, b)
19
+ a = a.to_bn if a.respond_to?(:to_bn)
20
+ b = b.to_bn if b.respond_to?(:to_bn)
21
+ a = a.to_s(2) if a.is_a?(OpenSSL::BN)
22
+ b = b.to_s(2) if b.is_a?(OpenSSL::BN)
23
+ as = a.bytesize
24
+ bs = b.bytesize
25
+ a.ljust!(bs, ZERO_PAD) if as < bs
26
+ b.ljust!(as, ZERO_PAD) if bs < as
27
+ return OpenSSL::BN.new(a.unpack(UCHAR_PACK).zip(b.unpack(UCHAR_PACK)).map do |ac,bc|
28
+ next (ac ^ bc)
29
+ end.reverse.pack(UCHAR_PACK), 2)
30
+ end
31
+
15
32
  end
16
33
  end
17
34
 
35
+ require 'jose/jwa/field_element'
36
+ require 'jose/jwa/edwards_point'
37
+ require 'jose/jwa/sha3'
38
+
18
39
  require 'jose/jwa/aes_kw'
19
40
  require 'jose/jwa/concat_kdf'
41
+ require 'jose/jwa/curve25519'
42
+ require 'jose/jwa/curve448'
20
43
  require 'jose/jwa/pkcs1'
21
44
  require 'jose/jwa/pkcs7'
@@ -0,0 +1,102 @@
1
+ module JOSE::JWA::Curve25519
2
+
3
+ extend self
4
+
5
+ MUTEX = Mutex.new
6
+
7
+ @__implementations__ = []
8
+ @__ruby_implementations__ = []
9
+
10
+ def __implementation__
11
+ return MUTEX.synchronize { @__implementation__ ||= __pick_best_implementation__ }
12
+ end
13
+
14
+ def __implementation__=(implementation)
15
+ return MUTEX.synchronize { @__implementation__ = implementation }
16
+ end
17
+
18
+ def __register__(implementation, ruby = false)
19
+ MUTEX.synchronize {
20
+ if ruby
21
+ @__ruby_implementations__.unshift(implementation)
22
+ else
23
+ @__implementations__.unshift(implementation)
24
+ end
25
+ __config_change__(false)
26
+ implementation
27
+ }
28
+ end
29
+
30
+ def __config_change__(lock = true)
31
+ MUTEX.lock if lock
32
+ @__implementation__ = __pick_best_implementation__ if @__implementation__.nil? or @__implementation__.__ruby__? or not @__implementation__.__supported__?
33
+ MUTEX.unlock if lock
34
+ end
35
+
36
+ def ed25519_keypair(secret = nil)
37
+ return (@__implementation__ || __implementation__).ed25519_keypair(secret)
38
+ end
39
+
40
+ def ed25519_secret_to_public(sk)
41
+ return (@__implementation__ || __implementation__).ed25519_secret_to_public(sk)
42
+ end
43
+
44
+ def ed25519_sign(m, sk)
45
+ return (@__implementation__ || __implementation__).ed25519_sign(m, sk)
46
+ end
47
+
48
+ def ed25519_verify(sig, m, pk)
49
+ return (@__implementation__ || __implementation__).ed25519_verify(sig, m, pk)
50
+ end
51
+
52
+ def ed25519ph_keypair(secret = nil)
53
+ return (@__implementation__ || __implementation__).ed25519ph_keypair(secret)
54
+ end
55
+
56
+ def ed25519ph_secret_to_public(sk)
57
+ return (@__implementation__ || __implementation__).ed25519ph_secret_to_public(sk)
58
+ end
59
+
60
+ def ed25519ph_sign(m, sk)
61
+ return (@__implementation__ || __implementation__).ed25519ph_sign(m, sk)
62
+ end
63
+
64
+ def ed25519ph_verify(sig, m, pk)
65
+ return (@__implementation__ || __implementation__).ed25519ph_verify(sig, m, pk)
66
+ end
67
+
68
+ def x25519_keypair(secret = nil)
69
+ return (@__implementation__ || __implementation__).x25519_keypair(secret)
70
+ end
71
+
72
+ def x25519_secret_to_public(sk)
73
+ return (@__implementation__ || __implementation__).x25519_secret_to_public(sk)
74
+ end
75
+
76
+ def x25519_shared_secret(pk, sk)
77
+ return (@__implementation__ || __implementation__).x25519_shared_secret(pk, sk)
78
+ end
79
+
80
+ private
81
+ def __pick_best_implementation__
82
+ implementation = nil
83
+ implementation = @__implementations__.detect do |implementation|
84
+ next implementation.__supported__?
85
+ end
86
+ implementation ||= @__ruby_implementations__.detect do |implementation|
87
+ next implementation.__supported__?
88
+ end
89
+ implementation ||= JOSE::JWA::Curve25519_Unsupported
90
+ return implementation
91
+ end
92
+
93
+ end
94
+
95
+ require 'jose/jwa/ed25519'
96
+ require 'jose/jwa/ed25519_rbnacl'
97
+ require 'jose/jwa/x25519'
98
+ require 'jose/jwa/x25519_rbnacl'
99
+
100
+ require 'jose/jwa/curve25519_unsupported'
101
+ require 'jose/jwa/curve25519_ruby'
102
+ require 'jose/jwa/curve25519_rbnacl'
@@ -0,0 +1,67 @@
1
+ module JOSE::JWA::Curve25519_RbNaCl
2
+
3
+ extend self
4
+
5
+ def __ruby__?; false; end
6
+
7
+ def __supported__?
8
+ return @supported ||= begin
9
+ begin
10
+ require 'rbnacl/libsodium'
11
+ rescue LoadError
12
+ end
13
+ begin
14
+ require 'rbnacl'
15
+ rescue LoadError
16
+ end
17
+ !!(defined?(RbNaCl::GroupElements::Curve25519))
18
+ end
19
+ end
20
+
21
+ def ed25519_keypair(secret = nil)
22
+ return JOSE::JWA::Ed25519_RbNaCl.keypair(secret)
23
+ end
24
+
25
+ def ed25519_secret_to_public(sk)
26
+ return JOSE::JWA::Ed25519_RbNaCl.sk_to_pk(sk)
27
+ end
28
+
29
+ def ed25519_sign(m, sk)
30
+ return JOSE::JWA::Ed25519_RbNaCl.sign(m, sk)
31
+ end
32
+
33
+ def ed25519_verify(sig, m, pk)
34
+ return JOSE::JWA::Ed25519_RbNaCl.verify(sig, m, pk)
35
+ end
36
+
37
+ def ed25519ph_keypair(secret = nil)
38
+ return JOSE::JWA::Ed25519_RbNaCl.keypair(secret)
39
+ end
40
+
41
+ def ed25519ph_secret_to_public(sk)
42
+ return JOSE::JWA::Ed25519_RbNaCl.sk_to_pk(sk)
43
+ end
44
+
45
+ def ed25519ph_sign(m, sk)
46
+ return JOSE::JWA::Ed25519_RbNaCl.sign_ph(m, sk)
47
+ end
48
+
49
+ def ed25519ph_verify(sig, m, pk)
50
+ return JOSE::JWA::Ed25519_RbNaCl.verify_ph(sig, m, pk)
51
+ end
52
+
53
+ def x25519_keypair(secret = nil)
54
+ return JOSE::JWA::X25519.keypair(secret)
55
+ end
56
+
57
+ def x25519_secret_to_public(sk)
58
+ return JOSE::JWA::X25519.sk_to_pk(sk)
59
+ end
60
+
61
+ def x25519_shared_secret(pk, sk)
62
+ return JOSE::JWA::X25519.shared_secret(pk, sk)
63
+ end
64
+
65
+ end
66
+
67
+ JOSE::JWA::Curve25519.__register__(JOSE::JWA::Curve25519_RbNaCl)
@@ -0,0 +1,54 @@
1
+ module JOSE::JWA::Curve25519_Ruby
2
+
3
+ extend self
4
+
5
+ def __ruby__?; true; end
6
+ def __supported__?; JOSE.__crypto_fallback__; end
7
+
8
+ def ed25519_keypair(secret = nil)
9
+ return JOSE::JWA::Ed25519.keypair(secret)
10
+ end
11
+
12
+ def ed25519_secret_to_public(sk)
13
+ return JOSE::JWA::Ed25519.sk_to_pk(sk)
14
+ end
15
+
16
+ def ed25519_sign(m, sk)
17
+ return JOSE::JWA::Ed25519.sign(m, sk)
18
+ end
19
+
20
+ def ed25519_verify(sig, m, pk)
21
+ return JOSE::JWA::Ed25519.verify(sig, m, pk)
22
+ end
23
+
24
+ def ed25519ph_keypair(secret = nil)
25
+ return JOSE::JWA::Ed25519.keypair(secret)
26
+ end
27
+
28
+ def ed25519ph_secret_to_public(sk)
29
+ return JOSE::JWA::Ed25519.sk_to_pk(sk)
30
+ end
31
+
32
+ def ed25519ph_sign(m, sk)
33
+ return JOSE::JWA::Ed25519.sign_ph(m, sk)
34
+ end
35
+
36
+ def ed25519ph_verify(sig, m, pk)
37
+ return JOSE::JWA::Ed25519.verify_ph(sig, m, pk)
38
+ end
39
+
40
+ def x25519_keypair(secret = nil)
41
+ return JOSE::JWA::X25519.keypair(secret)
42
+ end
43
+
44
+ def x25519_secret_to_public(sk)
45
+ return JOSE::JWA::X25519.sk_to_pk(sk)
46
+ end
47
+
48
+ def x25519_shared_secret(pk, sk)
49
+ return JOSE::JWA::X25519.shared_secret(pk, sk)
50
+ end
51
+
52
+ end
53
+
54
+ JOSE::JWA::Curve25519.__register__(JOSE::JWA::Curve25519_Ruby, true)