jose 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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)