jose 0.3.1 → 1.0.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 +4 -4
 - data/.travis.yml +5 -0
 - data/.yardopts +4 -0
 - data/CHANGELOG.md +7 -0
 - data/{LICENSE.txt → LICENSE.md} +0 -0
 - data/README.md +10 -3
 - data/docs/EncryptionAlgorithms.md +55 -0
 - data/docs/GettingStarted.md +137 -0
 - data/docs/KeyGeneration.md +263 -0
 - data/docs/SignatureAlgorithms.md +35 -0
 - data/lib/jose.rb +86 -22
 - data/lib/jose/jwa.rb +293 -0
 - data/lib/jose/jwa/concat_kdf.rb +2 -0
 - data/lib/jose/jwa/curve25519_ruby.rb +1 -1
 - data/lib/jose/jwa/curve448_ruby.rb +1 -1
 - data/lib/jose/jwa/ed448.rb +8 -8
 - data/lib/jose/jwe.rb +819 -11
 - data/lib/jose/jwe/alg_aes_gcm_kw.rb +1 -1
 - data/lib/jose/jwe/alg_aes_kw.rb +1 -1
 - data/lib/jose/jwe/alg_dir.rb +4 -4
 - data/lib/jose/jwe/alg_ecdh_es.rb +45 -18
 - data/lib/jose/jwe/alg_pbes2.rb +3 -3
 - data/lib/jose/jwe/alg_rsa.rb +1 -1
 - data/lib/jose/jwk.rb +639 -48
 - data/lib/jose/jwk/kty_ec.rb +22 -4
 - data/lib/jose/jwk/kty_oct.rb +16 -0
 - data/lib/jose/jwk/kty_okp_ed25519.rb +36 -0
 - data/lib/jose/jwk/kty_okp_ed25519ph.rb +36 -0
 - data/lib/jose/jwk/kty_okp_ed448.rb +36 -0
 - data/lib/jose/jwk/kty_okp_ed448ph.rb +36 -0
 - data/lib/jose/jwk/kty_okp_x25519.rb +28 -0
 - data/lib/jose/jwk/kty_okp_x448.rb +28 -0
 - data/lib/jose/jwk/kty_rsa.rb +8 -0
 - data/lib/jose/jwk/openssh_key.rb +278 -0
 - data/lib/jose/jws.rb +486 -21
 - data/lib/jose/jws/alg_none.rb +2 -2
 - data/lib/jose/jwt.rb +208 -14
 - data/lib/jose/version.rb +1 -1
 - metadata +9 -3
 
    
        data/lib/jose/jws.rb
    CHANGED
    
    | 
         @@ -1,21 +1,254 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module JOSE
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
              class SignedBinary < ::String
         
     | 
| 
      
 4 
     | 
    
         
            +
                # Expands a compacted signed binary or list of signed binaries into a map.
         
     | 
| 
      
 5 
     | 
    
         
            +
                # @see JOSE::JWS.expand
         
     | 
| 
       4 
6 
     | 
    
         
             
                def expand
         
     | 
| 
       5 
7 
     | 
    
         
             
                  return JOSE::JWS.expand(self)
         
     | 
| 
       6 
8 
     | 
    
         
             
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                # Returns the decoded payload portion of a signed binary or map without verifying the signature.
         
     | 
| 
      
 11 
     | 
    
         
            +
                # @see JOSE::JWS.peek_payload
         
     | 
| 
      
 12 
     | 
    
         
            +
                def peek_payload
         
     | 
| 
      
 13 
     | 
    
         
            +
                  return JOSE::JWS.peek_payload(self)
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                # Returns the decoded protected portion of a signed binary or map without verifying the signature.
         
     | 
| 
      
 17 
     | 
    
         
            +
                # @see JOSE::JWS.peek_protected
         
     | 
| 
      
 18 
     | 
    
         
            +
                def peek_protected
         
     | 
| 
      
 19 
     | 
    
         
            +
                  return JOSE::JWS.peek_protected(self)
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # Returns the decoded signature portion of a signed binary or map without verifying the signature.
         
     | 
| 
      
 23 
     | 
    
         
            +
                # @see JOSE::JWS.peek_signature
         
     | 
| 
      
 24 
     | 
    
         
            +
                def peek_signature
         
     | 
| 
      
 25 
     | 
    
         
            +
                  return JOSE::JWS.peek_signature(self)
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
       7 
27 
     | 
    
         
             
              end
         
     | 
| 
       8 
28 
     | 
    
         | 
| 
      
 29 
     | 
    
         
            +
              # Immutable signed Map structure based on {JOSE::Map JOSE::Map}.
         
     | 
| 
       9 
30 
     | 
    
         
             
              class SignedMap < JOSE::Map
         
     | 
| 
      
 31 
     | 
    
         
            +
                # Compacts an expanded signed map or signed list into a binary.
         
     | 
| 
      
 32 
     | 
    
         
            +
                # @see JOSE::JWS.compact
         
     | 
| 
       10 
33 
     | 
    
         
             
                def compact
         
     | 
| 
       11 
34 
     | 
    
         
             
                  return JOSE::JWS.compact(self)
         
     | 
| 
       12 
35 
     | 
    
         
             
                end
         
     | 
| 
       13 
36 
     | 
    
         
             
              end
         
     | 
| 
       14 
37 
     | 
    
         | 
| 
      
 38 
     | 
    
         
            +
              # JWS stands for JSON Web Signature which is defined in [RFC 7515](https://tools.ietf.org/html/rfc7515).
         
     | 
| 
      
 39 
     | 
    
         
            +
              #
         
     | 
| 
      
 40 
     | 
    
         
            +
              # ## Unsecured Signing Vulnerability
         
     | 
| 
      
 41 
     | 
    
         
            +
              #
         
     | 
| 
      
 42 
     | 
    
         
            +
              # The [`"none"`](https://tools.ietf.org/html/rfc7515#appendix-A.5) signing
         
     | 
| 
      
 43 
     | 
    
         
            +
              # algorithm is disabled by default to prevent accidental verification of empty
         
     | 
| 
      
 44 
     | 
    
         
            +
              # signatures (read about the vulnerability [here](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/)).
         
     | 
| 
      
 45 
     | 
    
         
            +
              #
         
     | 
| 
      
 46 
     | 
    
         
            +
              # You may also enable the `"none"` algorithm by setting the `JOSE_UNSECURED_SIGNING`
         
     | 
| 
      
 47 
     | 
    
         
            +
              # environment variable or by using {JOSE.unsecured_signing= JOSE.unsecured_signing=}.
         
     | 
| 
      
 48 
     | 
    
         
            +
              #
         
     | 
| 
      
 49 
     | 
    
         
            +
              # ## Strict Verification Recommended
         
     | 
| 
      
 50 
     | 
    
         
            +
              #
         
     | 
| 
      
 51 
     | 
    
         
            +
              # {JOSE::JWS.verify_strict JOSE::JWS.verify_strict} is recommended over {JOSE::JWS.verify JOSE::JWS.verify} so that
         
     | 
| 
      
 52 
     | 
    
         
            +
              # signing algorithms may be whitelisted during verification of signed input.
         
     | 
| 
      
 53 
     | 
    
         
            +
              #
         
     | 
| 
      
 54 
     | 
    
         
            +
              # ## Algorithms
         
     | 
| 
      
 55 
     | 
    
         
            +
              #
         
     | 
| 
      
 56 
     | 
    
         
            +
              # The following algorithms are currently supported by {JOSE::JWS JOSE::JWS} (some may need the {JOSE.crypto_fallback= JOSE.crypto_fallback=} option to be enabled):
         
     | 
| 
      
 57 
     | 
    
         
            +
              #
         
     | 
| 
      
 58 
     | 
    
         
            +
              #   * `"Ed25519"`
         
     | 
| 
      
 59 
     | 
    
         
            +
              #   * `"Ed25519ph"`
         
     | 
| 
      
 60 
     | 
    
         
            +
              #   * `"Ed448"`
         
     | 
| 
      
 61 
     | 
    
         
            +
              #   * `"Ed448ph"`
         
     | 
| 
      
 62 
     | 
    
         
            +
              #   * `"ES256"`
         
     | 
| 
      
 63 
     | 
    
         
            +
              #   * `"ES384"`
         
     | 
| 
      
 64 
     | 
    
         
            +
              #   * `"ES512"`
         
     | 
| 
      
 65 
     | 
    
         
            +
              #   * `"HS256"`
         
     | 
| 
      
 66 
     | 
    
         
            +
              #   * `"HS384"`
         
     | 
| 
      
 67 
     | 
    
         
            +
              #   * `"HS512"`
         
     | 
| 
      
 68 
     | 
    
         
            +
              #   * `"PS256"`
         
     | 
| 
      
 69 
     | 
    
         
            +
              #   * `"PS384"`
         
     | 
| 
      
 70 
     | 
    
         
            +
              #   * `"PS512"`
         
     | 
| 
      
 71 
     | 
    
         
            +
              #   * `"RS256"`
         
     | 
| 
      
 72 
     | 
    
         
            +
              #   * `"RS384"`
         
     | 
| 
      
 73 
     | 
    
         
            +
              #   * `"RS512"`
         
     | 
| 
      
 74 
     | 
    
         
            +
              #   * `"none"` (disabled by default, enable with {JOSE.unsecured_signing= JOSE.unsecured_signing=})
         
     | 
| 
      
 75 
     | 
    
         
            +
              #
         
     | 
| 
      
 76 
     | 
    
         
            +
              # ## Examples
         
     | 
| 
      
 77 
     | 
    
         
            +
              #
         
     | 
| 
      
 78 
     | 
    
         
            +
              # All of the example keys generated below can be found here: [https://gist.github.com/potatosalad/925a8b74d85835e285b9](https://gist.github.com/potatosalad/925a8b74d85835e285b9)
         
     | 
| 
      
 79 
     | 
    
         
            +
              #
         
     | 
| 
      
 80 
     | 
    
         
            +
              # ### <a name="EdDSA-25519-group">Ed25519 and Ed25519ph</a>
         
     | 
| 
      
 81 
     | 
    
         
            +
              #
         
     | 
| 
      
 82 
     | 
    
         
            +
              #     !!!ruby
         
     | 
| 
      
 83 
     | 
    
         
            +
              #     # let's generate the 2 keys we'll use below
         
     | 
| 
      
 84 
     | 
    
         
            +
              #     jwk_ed25519   = JOSE::JWK.generate_key([:okp, :Ed25519])
         
     | 
| 
      
 85 
     | 
    
         
            +
              #     jwk_ed25519ph = JOSE::JWK.generate_key([:okp, :Ed25519ph])
         
     | 
| 
      
 86 
     | 
    
         
            +
              #
         
     | 
| 
      
 87 
     | 
    
         
            +
              #     # Ed25519
         
     | 
| 
      
 88 
     | 
    
         
            +
              #     signed_ed25519 = JOSE::JWS.sign(jwk_ed25519, "{}", { "alg" => "Ed25519" }).compact
         
     | 
| 
      
 89 
     | 
    
         
            +
              #     # => "eyJhbGciOiJFZDI1NTE5In0.e30.xyg2LTblm75KbLFJtROZRhEgAFJdlqH9bhx8a9LO1yvLxNLhO9fLqnFuU3ojOdbObr8bsubPkPqUfZlPkGHXCQ"
         
     | 
| 
      
 90 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_ed25519, signed_ed25519).first
         
     | 
| 
      
 91 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 92 
     | 
    
         
            +
              #
         
     | 
| 
      
 93 
     | 
    
         
            +
              #     # Ed25519ph
         
     | 
| 
      
 94 
     | 
    
         
            +
              #     signed_ed25519ph = JOSE::JWS.sign(jwk_ed25519ph, "{}", { "alg" => "Ed25519ph" }).compact
         
     | 
| 
      
 95 
     | 
    
         
            +
              #     # => "eyJhbGciOiJFZDI1NTE5cGgifQ.e30.R3je4TTxQvoBOupIKkel_b8eW-G8KaWmXuC14NMGSCcHCTalURtMmVqX2KbcIpFBeI-OKP3BLHNIpt1keKveDg"
         
     | 
| 
      
 96 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_ed25519ph, signed_ed25519ph).first
         
     | 
| 
      
 97 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 98 
     | 
    
         
            +
              #
         
     | 
| 
      
 99 
     | 
    
         
            +
              # ### <a name="EdDSA-448-group">Ed448 and Ed448ph</a>
         
     | 
| 
      
 100 
     | 
    
         
            +
              #
         
     | 
| 
      
 101 
     | 
    
         
            +
              #     !!!ruby
         
     | 
| 
      
 102 
     | 
    
         
            +
              #     # let's generate the 2 keys we'll use below
         
     | 
| 
      
 103 
     | 
    
         
            +
              #     jwk_ed448   = JOSE::JWK.generate_key([:okp, :Ed448])
         
     | 
| 
      
 104 
     | 
    
         
            +
              #     jwk_ed448ph = JOSE::JWK.generate_key([:okp, :Ed448ph])
         
     | 
| 
      
 105 
     | 
    
         
            +
              #
         
     | 
| 
      
 106 
     | 
    
         
            +
              #     # Ed448
         
     | 
| 
      
 107 
     | 
    
         
            +
              #     signed_ed448 = JOSE::JWS.sign(jwk_ed448, "{}", { "alg" => "Ed448" }).compact
         
     | 
| 
      
 108 
     | 
    
         
            +
              #     # => "eyJhbGciOiJFZDQ0OCJ9.e30.UlqTx962FvZP1G5pZOrScRXlAB0DJI5dtZkknNTm1E70AapkONi8vzpvKd355czflQdc7uyOzTeAz0-eLvffCKgWm_zebLly7L3DLBliynQk14qgJgz0si-60mBFYOIxRghk95kk5hCsFpxpVE45jRIA"
         
     | 
| 
      
 109 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_ed448, signed_ed448).first
         
     | 
| 
      
 110 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 111 
     | 
    
         
            +
              #
         
     | 
| 
      
 112 
     | 
    
         
            +
              #     # Ed448ph
         
     | 
| 
      
 113 
     | 
    
         
            +
              #     signed_ed448ph = JOSE::JWS.sign(jwk_ed448ph, "{}", { "alg" => "Ed448ph" }).compact
         
     | 
| 
      
 114 
     | 
    
         
            +
              #     # => "eyJhbGciOiJFZDQ0OHBoIn0.e30._7wxQF8Am-Fg3E-KgREXBv3Gr2vqLM6ja_7hs6kA5EakCrJVQ2QiAHrr4NriLABmiPbVd7F7IiaAApyR3Ud4ak3lGcHVxSyksjJjvBUbKnSB_xkT6v_QMmx27hV08JlxskUkfvjAG0-yKGC8BXoT9R0A"
         
     | 
| 
      
 115 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_ed448ph, signed_ed448ph).first
         
     | 
| 
      
 116 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 117 
     | 
    
         
            +
              #
         
     | 
| 
      
 118 
     | 
    
         
            +
              # ### <a name="ECDSA-group">ES256, ES384, and ES512</a>
         
     | 
| 
      
 119 
     | 
    
         
            +
              #
         
     | 
| 
      
 120 
     | 
    
         
            +
              #     !!!ruby
         
     | 
| 
      
 121 
     | 
    
         
            +
              #     # let's generate the 3 keys we'll use below
         
     | 
| 
      
 122 
     | 
    
         
            +
              #     jwk_es256 = JOSE::JWK.generate_key([:ec, "P-256"])
         
     | 
| 
      
 123 
     | 
    
         
            +
              #     jwk_es384 = JOSE::JWK.generate_key([:ec, "P-384"])
         
     | 
| 
      
 124 
     | 
    
         
            +
              #     jwk_es512 = JOSE::JWK.generate_key([:ec, "P-521"])
         
     | 
| 
      
 125 
     | 
    
         
            +
              #
         
     | 
| 
      
 126 
     | 
    
         
            +
              #     # ES256
         
     | 
| 
      
 127 
     | 
    
         
            +
              #     signed_es256 = JOSE::JWS.sign(jwk_es256, "{}", { "alg" => "ES256" }).compact
         
     | 
| 
      
 128 
     | 
    
         
            +
              #     # => "eyJhbGciOiJFUzI1NiJ9.e30.nb7cEQQuIi2NgcP5A468FHGG8UZg8gWZjloISyVIwNh3X6FiTTFZsvc0mL3RnulWoNJzKF6xwhae3botI1LbRg"
         
     | 
| 
      
 129 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_es256, signed_es256).first
         
     | 
| 
      
 130 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 131 
     | 
    
         
            +
              #
         
     | 
| 
      
 132 
     | 
    
         
            +
              #     # ES384
         
     | 
| 
      
 133 
     | 
    
         
            +
              #     signed_es384 = JOSE::JWS.sign(jwk_es384, "{}", { "alg" => "ES384" }).compact
         
     | 
| 
      
 134 
     | 
    
         
            +
              #     # => "eyJhbGciOiJFUzM4NCJ9.e30.-2kZkNe66y2SprhgvvtMa0qBrSb2imPhMYkbi_a7vx-vpEHuVKsxCpUyNVLe5_CXaHWhHyc2rNi4uEfU73c8XQB3e03rg_JOj0H5XGIGS5G9f4RmNMSCiYGwqshLSDFI"
         
     | 
| 
      
 135 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_es384, signed_es384).first
         
     | 
| 
      
 136 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 137 
     | 
    
         
            +
              #
         
     | 
| 
      
 138 
     | 
    
         
            +
              #     # ES512
         
     | 
| 
      
 139 
     | 
    
         
            +
              #     signed_es512 = JOSE::JWS.sign(jwk_es512, "{}", { "alg" => "ES512" }).compact
         
     | 
| 
      
 140 
     | 
    
         
            +
              #     # => "eyJhbGciOiJFUzUxMiJ9.e30.AOIw4KTq5YDu6QNrAYKtFP8R5IljAbhqXuPK1dUARPqlfc5F3mM0kmSh5KOVNHDmdCdapBv0F3b6Hl6glFDPlxpiASuSWtvvs9K8_CRfSkEzvToj8wf3WLGOarQHDwYXtlZoki1zMPGeWABwafTZNQaItNSpqYd_P9GtN0XM3AALdua0"
         
     | 
| 
      
 141 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_es512, signed_es512).first
         
     | 
| 
      
 142 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 143 
     | 
    
         
            +
              #
         
     | 
| 
      
 144 
     | 
    
         
            +
              # ### <a name="HMACSHA2-group">HS256, HS384, and HS512</a>
         
     | 
| 
      
 145 
     | 
    
         
            +
              #
         
     | 
| 
      
 146 
     | 
    
         
            +
              #     !!!ruby
         
     | 
| 
      
 147 
     | 
    
         
            +
              #     # let's generate the 3 keys we'll use below
         
     | 
| 
      
 148 
     | 
    
         
            +
              #     jwk_hs256 = JOSE::JWK.generate_key([:oct, 16])
         
     | 
| 
      
 149 
     | 
    
         
            +
              #     jwk_hs384 = JOSE::JWK.generate_key([:oct, 24])
         
     | 
| 
      
 150 
     | 
    
         
            +
              #     jwk_hs512 = JOSE::JWK.generate_key([:oct, 32])
         
     | 
| 
      
 151 
     | 
    
         
            +
              #
         
     | 
| 
      
 152 
     | 
    
         
            +
              #     # HS256
         
     | 
| 
      
 153 
     | 
    
         
            +
              #     signed_hs256 = JOSE::JWS.sign(jwk_hs256, "{}", { "alg" => "HS256" }).compact
         
     | 
| 
      
 154 
     | 
    
         
            +
              #     # => "eyJhbGciOiJIUzI1NiJ9.e30.r2JwwMFHECoDZlrETLT-sgFT4qN3w0MLee9MrgkDwXs"
         
     | 
| 
      
 155 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_hs256, signed_hs256).first
         
     | 
| 
      
 156 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 157 
     | 
    
         
            +
              #
         
     | 
| 
      
 158 
     | 
    
         
            +
              #     # HS384
         
     | 
| 
      
 159 
     | 
    
         
            +
              #     signed_hs384 = JOSE::JWS.sign(jwk_hs384, "{}", { "alg" => "HS384" }).compact
         
     | 
| 
      
 160 
     | 
    
         
            +
              #     # => "eyJhbGciOiJIUzM4NCJ9.e30.brqQFXXM0XtMWDdKf0foEQcvK18swcoDkxBqCPeed_IO317_tisr60H2mz79SlNR"
         
     | 
| 
      
 161 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_hs384, signed_hs384).first
         
     | 
| 
      
 162 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 163 
     | 
    
         
            +
              #
         
     | 
| 
      
 164 
     | 
    
         
            +
              #     # HS512
         
     | 
| 
      
 165 
     | 
    
         
            +
              #     signed_hs512 = JOSE::JWS.sign(jwk_hs512, "{}", { "alg" => "HS512" }).compact
         
     | 
| 
      
 166 
     | 
    
         
            +
              #     # => "eyJhbGciOiJIUzUxMiJ9.e30.ge1JYomO8Fyl6sgxLbc4g3AMPbaMHLmeTl0jrUYAJZSloN9j4VyhjucX8d-RWIlMjzdG0xyklw53k1-kaTlRVQ"
         
     | 
| 
      
 167 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_hs512, signed_hs512).first
         
     | 
| 
      
 168 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 169 
     | 
    
         
            +
              #
         
     | 
| 
      
 170 
     | 
    
         
            +
              # ### <a name="RSASSAPSS-group">PS256, PS384, and PS512</a>
         
     | 
| 
      
 171 
     | 
    
         
            +
              #
         
     | 
| 
      
 172 
     | 
    
         
            +
              #     !!!ruby
         
     | 
| 
      
 173 
     | 
    
         
            +
              #     # let's generate the 3 keys we'll use below (cutkey must be installed as a dependency)
         
     | 
| 
      
 174 
     | 
    
         
            +
              #     jwk_ps256 = JOSE::JWK.generate_key([:rsa, 2048])
         
     | 
| 
      
 175 
     | 
    
         
            +
              #     jwk_ps384 = JOSE::JWK.generate_key([:rsa, 4096])
         
     | 
| 
      
 176 
     | 
    
         
            +
              #     jwk_ps512 = JOSE::JWK.generate_key([:rsa, 8192]) # this may take a few seconds
         
     | 
| 
      
 177 
     | 
    
         
            +
              #
         
     | 
| 
      
 178 
     | 
    
         
            +
              #     # PS256
         
     | 
| 
      
 179 
     | 
    
         
            +
              #     signed_ps256 = JOSE::JWS.sign(jwk_ps256, "{}", { "alg" => "PS256" }).compact
         
     | 
| 
      
 180 
     | 
    
         
            +
              #     # => "eyJhbGciOiJQUzI1NiJ9.e30.RY5A3rG2TjmdlARE57eSSSFE6plkuQPKLKsyqz3WrqKRWZgSrvROACRTzoGyrx1sNvQEZJLZ-xVhrFvP-80Q14XzQbPfYLubvn-2wcMNCmih3OVQNVtFdFjA5U2NG-sF-SWAUmm9V_DvMShFGG0qHxLX7LqT83lAIgEulgsytb0xgOjtJObBru5jLjN_uEnc7fCfnxi3my1GAtnrs9NiKvMfuIVlttvOORDFBTO2aFiCv1F-S6Xgj16rc0FGImG0x3amQcmFAD9g41KY0_KsCXgUfoiVpC6CqO6saRC4UDykks91B7Nuoxjsm3nKWa_4vKh9QJy-V8Sf0gHxK58j8Q"
         
     | 
| 
      
 181 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_ps256, signed_ps256).first
         
     | 
| 
      
 182 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 183 
     | 
    
         
            +
              #
         
     | 
| 
      
 184 
     | 
    
         
            +
              #     # PS384
         
     | 
| 
      
 185 
     | 
    
         
            +
              #     signed_ps384 = JOSE::JWS.sign(jwk_ps384, "{}", { "alg" => "PS384" }).compact
         
     | 
| 
      
 186 
     | 
    
         
            +
              #     # => "eyJhbGciOiJQUzM4NCJ9.e30.xmYVenIhi75hDMy3bnL6WVpVlTzYmO1ejOZeq9AkSjkp_STrdIp6uUEs9H_y7CLD9LrGYYHDNDl9WmoH6cn95WZT9KJgAVNFFYd8owY6JUHGKU1jUbLkptAgvdphVpWZ1C5fVCRt4vmp8K9f6jy3er9jCBNjl9gSBdmToFwYdXI26ZKSBjfoVm2tFFQIOThye4YQWCWHbzSho6J7d5ATje72L30zDvWXavJ-XNvof5Tkju4WQQB-ukFoqTw4yV8RVwCa-DX61I1hNrq-Zr75_iWmHak3GqNkg5ACBEjDtvtyxJizqy9KINKSlbB9jGztiWoEiXZ6wJ5sSJ6ZrSFJuQVEmns_dLqzpSHEFkWfczEV_gj9Eu_EXwMp9YQlQ3GktfXaz-mzH_jUaLmudEUskQGCiR92gK9KR6_ROQPJfD54Tkqdh6snwg6y17k8GdlTc5qMM3V84q3R6zllmhrRhV1Dlduc0MEqKcsQSX_IX21-sfiVMIcUsW73dIPXVZI2jsNlEHKqwMjWdSfjYUf3YApxSGERU3u4lRS3F0yRrZur8KWS3ToilApjg0cNg9jKas8g8C8ZPgGFYM6StVxUnXRmsJILDnsZMIPjbUDAPHhB0DwLwOB7OqGUBcItX-zwur1OVnHR7aIh1DbfWfyTIml8VIhYfGfazgXfgQVcGEM"
         
     | 
| 
      
 187 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_ps384, signed_ps384).first
         
     | 
| 
      
 188 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 189 
     | 
    
         
            +
              #
         
     | 
| 
      
 190 
     | 
    
         
            +
              #     # PS512
         
     | 
| 
      
 191 
     | 
    
         
            +
              #     signed_ps512 = JOSE::JWS.sign(jwk_ps512, "{}", { "alg" => "PS512" }).compact
         
     | 
| 
      
 192 
     | 
    
         
            +
              #     # => "eyJhbGciOiJQUzUxMiJ9.e30.fJe52-PF3I7UrpQamLCnmVAGkBhP0HVeJi48qZqaFc1-_tQEiYTfxuwQBDlt01GQWpjTZRb097bZF6RcrKWwRHyAo3otOZdR32emWfOHddWLL3qotj_fTaDR2-OhLixwce6mFjnHqppHH1zjCmgbKPG8S2cAadNd5w10VR-IS6LdnFRhNZOahuuB7dzCEJaSjkGfm3_9xdj3I0ZRl4fauR_LO9NQIyvMMeCFevowz1sVGG1G-I2njPrEXvxhAMp7y2mao5Yik8UUORXRjcn2Wai3umy8Yh4nHYU5qqruHjLjDwudCPNDjxjg294z1uAUpt7S0v7VbrkgUvgutTFAT-bcHywFODiycajQuqIpFp1TCUAq3Xe2yk4DTRduvPIKcPkJQnFrVkClJAU9A4D4602xpdK-z2uCgWsBVHVokf5-9ba5EqVb8BJx2xYZUIA5CdrIiTBfoe_cI5Jh92uprcWC_llio2ZJvGdQpPgwCgca7-RQ94LAmIA4u3mAndrZj_z48T2GjHbaKzl18FOPQH0XEvK_W5oypUe5NOGlz9mMGZigbFqBY2lM-7oVVYc4ZA3VFy8Dv1nWhU6DGb2NnDnQUyChllyBREuZbwrkOTQEvqqdV-6lM6VwXNu1gqc3YHly9W6u5CmsnxtvlIxsUVg679HiqdtdWxLSaIJObd9Xji56-eEkWMEA08SNy9p-F9AgHOxzoZqgrAQDEwqyEwqoAW681xLc5Vck580AQDxO9Ha4IqLIPirpO5EODQjOd8-S_SlAP5o_wz1Oh38MC5T5V13PqPuZ70dbggB4bUgVaHYC4FE4XHCqP7W3xethaPc68cY9-g9f1RUvthmnEYXSRpvyaMY3iX0txZazWIS_Jg7pNTCEaWr9JCLTZd1MiLbFowPvKYGM-z-39K31OUbq5PIScy0I9OOz9joecm8KsCesA2ysPph1E7cL7Etiw5tGhCFzcdQwm8Gm6SDwj8vCEcZUkXeZJfhlS1cJtZk1sNu3KZNndevtZjRWaXi2m4WNKVxVE-nuaF7V3GWfDemh9RXxyFK8OC8aYLIqcc2pAKJM47ANVty2ll1xaCIB3q3CKdnk5fmsnzKkQI9SjKy70p9TWT-NNoYU682KG_mZo-ByEs5CvJ8w7qysmX8Xpb2I6oSJf7S3qjbqkqtXQcV5MuQ232vk7-g42CcQGL82xvRc09TuvwnmykpKHmjUaJ4U9k9zTN3g2iTdpkvl6vbnND9uG1SBaieVeFYWCT-6VdhovEiD9bvIdA7D_R7NZO8YHBt_lfBQRle_jDyLzHSlkP6kt9dYRhrc2SNMzF_4i3iEUAihbaQYvbNsGwWrHqyGofnva20pRXwc4GxOlw"
         
     | 
| 
      
 193 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_ps512, signed_ps512).first
         
     | 
| 
      
 194 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 195 
     | 
    
         
            +
              #
         
     | 
| 
      
 196 
     | 
    
         
            +
              # ### <a name="RSASSAPKCS1_5-group">RS256, RS384, and RS512</a>
         
     | 
| 
      
 197 
     | 
    
         
            +
              #
         
     | 
| 
      
 198 
     | 
    
         
            +
              #     !!!ruby
         
     | 
| 
      
 199 
     | 
    
         
            +
              #     # let's generate the 3 keys we'll use below
         
     | 
| 
      
 200 
     | 
    
         
            +
              #     jwk_rs256 = JOSE::JWK.generate_key([:rsa, 1024])
         
     | 
| 
      
 201 
     | 
    
         
            +
              #     jwk_rs384 = JOSE::JWK.generate_key([:rsa, 2048])
         
     | 
| 
      
 202 
     | 
    
         
            +
              #     jwk_rs512 = JOSE::JWK.generate_key([:rsa, 4096])
         
     | 
| 
      
 203 
     | 
    
         
            +
              #
         
     | 
| 
      
 204 
     | 
    
         
            +
              #     # RS256
         
     | 
| 
      
 205 
     | 
    
         
            +
              #     signed_rs256 = JOSE::JWS.sign(jwk_rs256, "{}", { "alg" => "RS256" }).compact
         
     | 
| 
      
 206 
     | 
    
         
            +
              #     # => "eyJhbGciOiJSUzI1NiJ9.e30.C0J8v5R-sEe9-g_s0SMgPorCh8VDdaZ9gLpWNm1Tn1Cv2xRph1Xn9Rzm10ZCEs84sj7kxA4v28fVShQ_P1AHN83yQ2mvstkKwsuwXxr-cludx_NLQL5CKKQtTR0ITD_pxUowjfAkBYuJv0677jUj-8lGKs1P5e2dbwW9IqFe4uE"
         
     | 
| 
      
 207 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_rs256, signed_rs256).first
         
     | 
| 
      
 208 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 209 
     | 
    
         
            +
              #
         
     | 
| 
      
 210 
     | 
    
         
            +
              #     # RS384
         
     | 
| 
      
 211 
     | 
    
         
            +
              #     signed_rs384 = JOSE::JWS.sign(jwk_rs384, "{}", { "alg" => "RS384" }).compact
         
     | 
| 
      
 212 
     | 
    
         
            +
              #     # => "eyJhbGciOiJSUzM4NCJ9.e30.fvPxeNhO0oitOsdqFmrBgpGE7Gn_NdJ1J8F5ArKon54pdHB2v30hua9wbG4V2Hr-hNAyflaBJtoGAwIpKVkfHn-IW7d06hKw_Hv0ecG-VvZr60cK2IJnHS149Htz_652egThZh1GIKRZN1IrRVlraLMozFcWP0Ojc-L-g5XjcTFafesmV0GFGfFubAiQWEiWIgNV3822L-wPe7ZGeFe5yYsZ70WMHQQ1tSuNsm5QUOUVInOThAhJ30FRTCNFgv46l4TEF9aaI9443cKAbwzd_EavD0FpvgpwEhGyNTVx0sxiCZIYUE_jN53aSaHXB82d0xwIr2-GXlr3Y-dLwERIMw"
         
     | 
| 
      
 213 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_rs384, signed_rs384).first
         
     | 
| 
      
 214 
     | 
    
         
            +
              #     # => true
         
     | 
| 
      
 215 
     | 
    
         
            +
              #
         
     | 
| 
      
 216 
     | 
    
         
            +
              #     # RS512
         
     | 
| 
      
 217 
     | 
    
         
            +
              #     signed_rs512 = JOSE::JWS.sign(jwk_rs512, "{}", { "alg" => "RS512" }).compact
         
     | 
| 
      
 218 
     | 
    
         
            +
              #     # => "eyJhbGciOiJSUzUxMiJ9.e30.le2_kCnmj6Y02bl16Hh5EPqmLsFkB3YZpiEfvmA6xfdg9I3QJ5uSgOejs_HpuIbItuMFUdcqtkfW45_6YKlI7plB49iWiNnWY0PLxsvbiZaSmT4R4dOUWx9KlO_Ui5SE94XkigUoFanDTHTr9bh4NpvoIaNdi_xLdC7FYA-AqZspegRcgY-QZQv4kbD3NQJtxsEiAXk8-C8CX3lF6haRlh7s4pyAmgj7SJeElsPjhPNVZ7EduhTLZfVwiLrRmzLKQ6dJ_PrZDig1lgl9jf2NjzcsFpt6lvfrMsDdIQEGyJoh53-zXiD_ltyAZGS3pX-_tHRxoAZ1SyAPkkC4cCra6wc-03sBQPoUa26xyyhrgf4h7E2l-JqhKPXT7pJv6AbRPgKUH4prEH636gpoWQrRc-JxbDIJHR0ShdL8ssf5e-rKpcVVAZKnRI64NbSKXTg-JtDxhU9QG8JVEkHqOxSeo-VSXOoExdmm8lCfqylrw7qmDxjEwOq7TGjhINyjVaK1Op_64BWVuCzgooea6G2ZvCTIEl0-k8wY8s9VC7hxSrsgCAnpWeKpIcbLQoDIoyasG-6Qb5OuSLR367eg9NAQ8WMTbrrQkm-KLNCYvMFaxmlWzBFST2JDmIr0VH9BzXRAdfG81SymuyFA7_FdpiVYwAwEGR4Q5HYEpequ38tHu3Y"
         
     | 
| 
      
 219 
     | 
    
         
            +
              #     JOSE::JWS.verify(jwk_rs512, signed_rs512).first
         
     | 
| 
      
 220 
     | 
    
         
            +
              #     # => true
         
     | 
| 
       15 
221 
     | 
    
         
             
              class JWS < Struct.new(:alg, :b64, :fields)
         
     | 
| 
       16 
222 
     | 
    
         | 
| 
       17 
223 
     | 
    
         
             
                # Decode API
         
     | 
| 
       18 
224 
     | 
    
         | 
| 
      
 225 
     | 
    
         
            +
                # Converts a binary or map into a {JOSE::JWS JOSE::JWS}.
         
     | 
| 
      
 226 
     | 
    
         
            +
                #
         
     | 
| 
      
 227 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 228 
     | 
    
         
            +
                #     JOSE::JWS.from({ "alg" => "HS256" })
         
     | 
| 
      
 229 
     | 
    
         
            +
                #     # => #<struct JOSE::JWS
         
     | 
| 
      
 230 
     | 
    
         
            +
                #     #  alg=#<struct JOSE::JWS::ALG_HMAC hmac=OpenSSL::Digest::SHA256>,
         
     | 
| 
      
 231 
     | 
    
         
            +
                #     #  b64=nil,
         
     | 
| 
      
 232 
     | 
    
         
            +
                #     #  fields=JOSE::Map[]>
         
     | 
| 
      
 233 
     | 
    
         
            +
                #     JOSE::JWS.from("{\"alg\":\"HS256\"}")
         
     | 
| 
      
 234 
     | 
    
         
            +
                #     # => #<struct JOSE::JWS
         
     | 
| 
      
 235 
     | 
    
         
            +
                #     #  alg=#<struct JOSE::JWS::ALG_HMAC hmac=OpenSSL::Digest::SHA256>,
         
     | 
| 
      
 236 
     | 
    
         
            +
                #     #  b64=nil,
         
     | 
| 
      
 237 
     | 
    
         
            +
                #     #  fields=JOSE::Map[]>
         
     | 
| 
      
 238 
     | 
    
         
            +
                #
         
     | 
| 
      
 239 
     | 
    
         
            +
                # Support for custom algorithms may be added by specifying `:alg` under `modules`:
         
     | 
| 
      
 240 
     | 
    
         
            +
                #
         
     | 
| 
      
 241 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 242 
     | 
    
         
            +
                #     JOSE::JWS.from({ "alg" => "custom" }, { alg: MyCustomAlgorithm })
         
     | 
| 
      
 243 
     | 
    
         
            +
                #     # => #<struct JOSE::JWS
         
     | 
| 
      
 244 
     | 
    
         
            +
                #     #  alg=#<MyCustomAlgorithm:0x007f8c5419ff68>,
         
     | 
| 
      
 245 
     | 
    
         
            +
                #     #  b64=nil,
         
     | 
| 
      
 246 
     | 
    
         
            +
                #     #  fields=JOSE::Map[]>
         
     | 
| 
      
 247 
     | 
    
         
            +
                #
         
     | 
| 
      
 248 
     | 
    
         
            +
                # *Note:* `MyCustomAlgorithm` must implement the methods mentioned in other alg modules.
         
     | 
| 
      
 249 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, String, JOSE::JWS, Array<JOSE::Map, Hash, String, JOSE::JWS>] object
         
     | 
| 
      
 250 
     | 
    
         
            +
                # @param [Hash] modules
         
     | 
| 
      
 251 
     | 
    
         
            +
                # @return [JOSE::JWS, Array<JOSE::JWS>]
         
     | 
| 
       19 
252 
     | 
    
         
             
                def self.from(object, modules = {})
         
     | 
| 
       20 
253 
     | 
    
         
             
                  case object
         
     | 
| 
       21 
254 
     | 
    
         
             
                  when JOSE::Map, Hash
         
     | 
| 
         @@ -24,61 +257,121 @@ module JOSE 
     | 
|
| 
       24 
257 
     | 
    
         
             
                    return from_binary(object, modules)
         
     | 
| 
       25 
258 
     | 
    
         
             
                  when JOSE::JWS
         
     | 
| 
       26 
259 
     | 
    
         
             
                    return object
         
     | 
| 
      
 260 
     | 
    
         
            +
                  when Array
         
     | 
| 
      
 261 
     | 
    
         
            +
                    return object.map { |obj| from(obj, modules) }
         
     | 
| 
       27 
262 
     | 
    
         
             
                  else
         
     | 
| 
       28 
     | 
    
         
            -
                    raise ArgumentError, "'object' must be a Hash, String,  
     | 
| 
      
 263 
     | 
    
         
            +
                    raise ArgumentError, "'object' must be a Hash, String, JOSE::JWS, or Array"
         
     | 
| 
       29 
264 
     | 
    
         
             
                  end
         
     | 
| 
       30 
265 
     | 
    
         
             
                end
         
     | 
| 
       31 
266 
     | 
    
         | 
| 
      
 267 
     | 
    
         
            +
                # Converts a binary into a {JOSE::JWS JOSE::JWS}.
         
     | 
| 
      
 268 
     | 
    
         
            +
                # @param [String, Array<String>] object
         
     | 
| 
      
 269 
     | 
    
         
            +
                # @param [Hash] modules
         
     | 
| 
      
 270 
     | 
    
         
            +
                # @return [JOSE::JWS, Array<JOSE::JWS>]
         
     | 
| 
       32 
271 
     | 
    
         
             
                def self.from_binary(object, modules = {})
         
     | 
| 
       33 
272 
     | 
    
         
             
                  case object
         
     | 
| 
       34 
273 
     | 
    
         
             
                  when String
         
     | 
| 
       35 
274 
     | 
    
         
             
                    return from_map(JOSE.decode(object), modules)
         
     | 
| 
      
 275 
     | 
    
         
            +
                  when Array
         
     | 
| 
      
 276 
     | 
    
         
            +
                    return object.map { |obj| from_binary(obj, modules) }
         
     | 
| 
       36 
277 
     | 
    
         
             
                  else
         
     | 
| 
       37 
     | 
    
         
            -
                    raise ArgumentError, "'object' must be a String"
         
     | 
| 
      
 278 
     | 
    
         
            +
                    raise ArgumentError, "'object' must be a String or Array"
         
     | 
| 
       38 
279 
     | 
    
         
             
                  end
         
     | 
| 
       39 
280 
     | 
    
         
             
                end
         
     | 
| 
       40 
281 
     | 
    
         | 
| 
      
 282 
     | 
    
         
            +
                # Reads file and calls {.from_binary} to convert into a {JOSE::JWS JOSE::JWS}.
         
     | 
| 
      
 283 
     | 
    
         
            +
                # @param [String] file
         
     | 
| 
      
 284 
     | 
    
         
            +
                # @param [Hash] modules
         
     | 
| 
      
 285 
     | 
    
         
            +
                # @return [JOSE::JWS]
         
     | 
| 
       41 
286 
     | 
    
         
             
                def self.from_file(file, modules = {})
         
     | 
| 
       42 
287 
     | 
    
         
             
                  return from_binary(File.binread(file), modules)
         
     | 
| 
       43 
288 
     | 
    
         
             
                end
         
     | 
| 
       44 
289 
     | 
    
         | 
| 
      
 290 
     | 
    
         
            +
                # Converts a map into a {JOSE::JWS JOSE::JWS}.
         
     | 
| 
      
 291 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, Array<JOSE::Map, Hash>] object
         
     | 
| 
      
 292 
     | 
    
         
            +
                # @param [Hash] modules
         
     | 
| 
      
 293 
     | 
    
         
            +
                # @return [JOSE::JWS, Array<JOSE::JWS>]
         
     | 
| 
       45 
294 
     | 
    
         
             
                def self.from_map(object, modules = {})
         
     | 
| 
       46 
295 
     | 
    
         
             
                  case object
         
     | 
| 
       47 
296 
     | 
    
         
             
                  when JOSE::Map, Hash
         
     | 
| 
       48 
297 
     | 
    
         
             
                    return from_fields(JOSE::JWS.new(nil, nil, JOSE::Map.new(object)), modules)
         
     | 
| 
      
 298 
     | 
    
         
            +
                  when Array
         
     | 
| 
      
 299 
     | 
    
         
            +
                    return object.map { |obj| from_map(obj, modules) }
         
     | 
| 
       49 
300 
     | 
    
         
             
                  else
         
     | 
| 
       50 
     | 
    
         
            -
                    raise ArgumentError, "'object' must be a Hash"
         
     | 
| 
      
 301 
     | 
    
         
            +
                    raise ArgumentError, "'object' must be a Hash or Array"
         
     | 
| 
       51 
302 
     | 
    
         
             
                  end
         
     | 
| 
       52 
303 
     | 
    
         
             
                end
         
     | 
| 
       53 
304 
     | 
    
         | 
| 
       54 
305 
     | 
    
         
             
                # Encode API
         
     | 
| 
       55 
306 
     | 
    
         | 
| 
      
 307 
     | 
    
         
            +
                # Converts a {JOSE::JWS JOSE::JWS} into a binary.
         
     | 
| 
      
 308 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, String, JOSE::JWS, Array<JOSE::Map, Hash, String, JOSE::JWS>] jws
         
     | 
| 
      
 309 
     | 
    
         
            +
                # @return [String, Array<String>]
         
     | 
| 
       56 
310 
     | 
    
         
             
                def self.to_binary(jws)
         
     | 
| 
       57 
     | 
    
         
            -
                   
     | 
| 
      
 311 
     | 
    
         
            +
                  if jws.is_a?(Array)
         
     | 
| 
      
 312 
     | 
    
         
            +
                    return from(jws).map { |obj| obj.to_binary }
         
     | 
| 
      
 313 
     | 
    
         
            +
                  else
         
     | 
| 
      
 314 
     | 
    
         
            +
                    return from(jws).to_binary
         
     | 
| 
      
 315 
     | 
    
         
            +
                  end
         
     | 
| 
       58 
316 
     | 
    
         
             
                end
         
     | 
| 
       59 
317 
     | 
    
         | 
| 
      
 318 
     | 
    
         
            +
                # Converts a {JOSE::JWS JOSE::JWS} into a binary.
         
     | 
| 
      
 319 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
       60 
320 
     | 
    
         
             
                def to_binary
         
     | 
| 
       61 
321 
     | 
    
         
             
                  return JOSE.encode(to_map)
         
     | 
| 
       62 
322 
     | 
    
         
             
                end
         
     | 
| 
       63 
323 
     | 
    
         | 
| 
      
 324 
     | 
    
         
            +
                # Calls {.to_binary} on a {JOSE::JWS JOSE::JWS} and then writes the binary to `file`.
         
     | 
| 
      
 325 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, String, JOSE::JWS] jws
         
     | 
| 
      
 326 
     | 
    
         
            +
                # @param [String] file
         
     | 
| 
      
 327 
     | 
    
         
            +
                # @return [Fixnum] bytes written
         
     | 
| 
       64 
328 
     | 
    
         
             
                def self.to_file(jws, file)
         
     | 
| 
       65 
329 
     | 
    
         
             
                  return from(jws).to_file(file)
         
     | 
| 
       66 
330 
     | 
    
         
             
                end
         
     | 
| 
       67 
331 
     | 
    
         | 
| 
      
 332 
     | 
    
         
            +
                # Calls {#to_binary} on a {JOSE::JWS JOSE::JWS} and then writes the binary to `file`.
         
     | 
| 
      
 333 
     | 
    
         
            +
                # @param [String] file
         
     | 
| 
      
 334 
     | 
    
         
            +
                # @return [Fixnum] bytes written
         
     | 
| 
       68 
335 
     | 
    
         
             
                def to_file(file)
         
     | 
| 
       69 
336 
     | 
    
         
             
                  return File.binwrite(file, to_binary)
         
     | 
| 
       70 
337 
     | 
    
         
             
                end
         
     | 
| 
       71 
338 
     | 
    
         | 
| 
      
 339 
     | 
    
         
            +
                # Converts a {JOSE::JWS JOSE::JWS} into a map.
         
     | 
| 
      
 340 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, String, JOSE::JWS, Array<JOSE::Map, Hash, String, JOSE::JWS>] jws
         
     | 
| 
      
 341 
     | 
    
         
            +
                # @return [JOSE::Map, Array<JOSE::Map>]
         
     | 
| 
       72 
342 
     | 
    
         
             
                def self.to_map(jws)
         
     | 
| 
       73 
     | 
    
         
            -
                   
     | 
| 
      
 343 
     | 
    
         
            +
                  if jws.is_a?(Array)
         
     | 
| 
      
 344 
     | 
    
         
            +
                    return from(jws).map { |obj| obj.to_map }
         
     | 
| 
      
 345 
     | 
    
         
            +
                  else
         
     | 
| 
      
 346 
     | 
    
         
            +
                    return from(jws).to_map
         
     | 
| 
      
 347 
     | 
    
         
            +
                  end
         
     | 
| 
       74 
348 
     | 
    
         
             
                end
         
     | 
| 
       75 
349 
     | 
    
         | 
| 
      
 350 
     | 
    
         
            +
                # Converts a {JOSE::JWS JOSE::JWS} into a map.
         
     | 
| 
      
 351 
     | 
    
         
            +
                # @return [JOSE::Map]
         
     | 
| 
       76 
352 
     | 
    
         
             
                def to_map
         
     | 
| 
       77 
     | 
    
         
            -
                   
     | 
| 
      
 353 
     | 
    
         
            +
                  map = alg.to_map(fields)
         
     | 
| 
      
 354 
     | 
    
         
            +
                  if b64 == false or b64 == true
         
     | 
| 
      
 355 
     | 
    
         
            +
                    map = map.put('b64', b64)
         
     | 
| 
      
 356 
     | 
    
         
            +
                  end
         
     | 
| 
      
 357 
     | 
    
         
            +
                  return map
         
     | 
| 
       78 
358 
     | 
    
         
             
                end
         
     | 
| 
       79 
359 
     | 
    
         | 
| 
       80 
360 
     | 
    
         
             
                # API
         
     | 
| 
       81 
361 
     | 
    
         | 
| 
      
 362 
     | 
    
         
            +
                # Compacts an expanded signed map or signed list into a binary.
         
     | 
| 
      
 363 
     | 
    
         
            +
                #
         
     | 
| 
      
 364 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 365 
     | 
    
         
            +
                #     JOSE::JWS.compact({
         
     | 
| 
      
 366 
     | 
    
         
            +
                #       "payload" => "e30",
         
     | 
| 
      
 367 
     | 
    
         
            +
                #       "protected" => "eyJhbGciOiJIUzI1NiJ9",
         
     | 
| 
      
 368 
     | 
    
         
            +
                #       "signature" => "5paAJxaOXSqRUIXrP_vJXUZu2SCBH-ojgP4D6Xr6GPU"
         
     | 
| 
      
 369 
     | 
    
         
            +
                #     })
         
     | 
| 
      
 370 
     | 
    
         
            +
                #     # => "eyJhbGciOiJIUzI1NiJ9.e30.5paAJxaOXSqRUIXrP_vJXUZu2SCBH-ojgP4D6Xr6GPU"
         
     | 
| 
      
 371 
     | 
    
         
            +
                #
         
     | 
| 
      
 372 
     | 
    
         
            +
                # @see JOSE::JWS.expand
         
     | 
| 
      
 373 
     | 
    
         
            +
                # @param [JOSE::SignedMap, JOSE::Map, Hash] map
         
     | 
| 
      
 374 
     | 
    
         
            +
                # @return [JOSE::SignedBinary]
         
     | 
| 
       82 
375 
     | 
    
         
             
                def self.compact(map)
         
     | 
| 
       83 
376 
     | 
    
         
             
                  if map.is_a?(Hash) or map.is_a?(JOSE::Map)
         
     | 
| 
       84 
377 
     | 
    
         
             
                    return JOSE::SignedBinary.new([
         
     | 
| 
         @@ -93,6 +386,18 @@ module JOSE 
     | 
|
| 
       93 
386 
     | 
    
         
             
                  end
         
     | 
| 
       94 
387 
     | 
    
         
             
                end
         
     | 
| 
       95 
388 
     | 
    
         | 
| 
      
 389 
     | 
    
         
            +
                # Expands a compacted signed binary or list of signed binaries into a map.
         
     | 
| 
      
 390 
     | 
    
         
            +
                #
         
     | 
| 
      
 391 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 392 
     | 
    
         
            +
                #     JOSE::JWS.expand("eyJhbGciOiJIUzI1NiJ9.e30.5paAJxaOXSqRUIXrP_vJXUZu2SCBH-ojgP4D6Xr6GPU")
         
     | 
| 
      
 393 
     | 
    
         
            +
                #     # => JOSE::SignedMap[
         
     | 
| 
      
 394 
     | 
    
         
            +
                #     #  "protected" => "eyJhbGciOiJIUzI1NiJ9",
         
     | 
| 
      
 395 
     | 
    
         
            +
                #     #  "payload" => "e30",
         
     | 
| 
      
 396 
     | 
    
         
            +
                #     #  "signature" => "5paAJxaOXSqRUIXrP_vJXUZu2SCBH-ojgP4D6Xr6GPU"]
         
     | 
| 
      
 397 
     | 
    
         
            +
                #
         
     | 
| 
      
 398 
     | 
    
         
            +
                # @see JOSE::JWS.compact
         
     | 
| 
      
 399 
     | 
    
         
            +
                # @param [JOSE::SignedBinary, String] binary
         
     | 
| 
      
 400 
     | 
    
         
            +
                # @return [JOSE::SignedMap]
         
     | 
| 
       96 
401 
     | 
    
         
             
                def self.expand(binary)
         
     | 
| 
       97 
402 
     | 
    
         
             
                  if binary.is_a?(String)
         
     | 
| 
       98 
403 
     | 
    
         
             
                    if binary.count('.') == 2 and (parts = binary.split('.', 3)).length == 3
         
     | 
| 
         @@ -110,18 +415,46 @@ module JOSE 
     | 
|
| 
       110 
415 
     | 
    
         
             
                  end
         
     | 
| 
       111 
416 
     | 
    
         
             
                end
         
     | 
| 
       112 
417 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
                 
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
      
 418 
     | 
    
         
            +
                # Generates a new {JOSE::JWK JOSE::JWK} based on the algorithms of the specified {JOSE::JWS JOSE::JWS}.
         
     | 
| 
      
 419 
     | 
    
         
            +
                #
         
     | 
| 
      
 420 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 421 
     | 
    
         
            +
                #     JOSE::JWS.generate_key({"alg" => "HS256"})
         
     | 
| 
      
 422 
     | 
    
         
            +
                #     # => #<struct JOSE::JWK
         
     | 
| 
      
 423 
     | 
    
         
            +
                #     #  keys=nil,
         
     | 
| 
      
 424 
     | 
    
         
            +
                #     #  kty=
         
     | 
| 
      
 425 
     | 
    
         
            +
                #     #   #<struct JOSE::JWK::KTY_oct
         
     | 
| 
      
 426 
     | 
    
         
            +
                #     #    oct="\x96G\x1DO\xE4 \xDA\x04o\xFA\xD4\x81\xE2\xADV\xCDH0bdBDq\r+<z\xF8\xB3,\x8C\x18">,
         
     | 
| 
      
 427 
     | 
    
         
            +
                #     #  fields=JOSE::Map["alg" => "HS256", "use" => "sig"]>
         
     | 
| 
      
 428 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, String, JOSE::JWS, Array<JOSE::Map, Hash, String, JOSE::JWS>] jws
         
     | 
| 
      
 429 
     | 
    
         
            +
                # @param [Hash] modules
         
     | 
| 
      
 430 
     | 
    
         
            +
                # @return [JOSE::JWK, Array<JOSE::JWK>]
         
     | 
| 
      
 431 
     | 
    
         
            +
                def self.generate_key(jws, modules = {})
         
     | 
| 
      
 432 
     | 
    
         
            +
                  if jws.is_a?(Array)
         
     | 
| 
      
 433 
     | 
    
         
            +
                    return from(jws, modules).map { |obj| obj.generate_key }
         
     | 
| 
      
 434 
     | 
    
         
            +
                  else
         
     | 
| 
      
 435 
     | 
    
         
            +
                    return from(jws, modules).generate_key
         
     | 
| 
      
 436 
     | 
    
         
            +
                  end
         
     | 
| 
       115 
437 
     | 
    
         
             
                end
         
     | 
| 
       116 
438 
     | 
    
         | 
| 
      
 439 
     | 
    
         
            +
                # Generates a new {JOSE::JWK JOSE::JWK} based on the algorithms of the specified {JOSE::JWS JOSE::JWS}.
         
     | 
| 
      
 440 
     | 
    
         
            +
                #
         
     | 
| 
      
 441 
     | 
    
         
            +
                # @see JOSE::JWS.generate_key
         
     | 
| 
      
 442 
     | 
    
         
            +
                # @return [JOSE::JWK]
         
     | 
| 
       117 
443 
     | 
    
         
             
                def generate_key
         
     | 
| 
       118 
444 
     | 
    
         
             
                  return alg.generate_key(fields)
         
     | 
| 
       119 
445 
     | 
    
         
             
                end
         
     | 
| 
       120 
446 
     | 
    
         | 
| 
      
 447 
     | 
    
         
            +
                # Merges map on right into map on left.
         
     | 
| 
      
 448 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, String, JOSE::JWS] left
         
     | 
| 
      
 449 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, String, JOSE::JWS] right
         
     | 
| 
      
 450 
     | 
    
         
            +
                # @return [JOSE::JWS]
         
     | 
| 
       121 
451 
     | 
    
         
             
                def self.merge(left, right)
         
     | 
| 
       122 
452 
     | 
    
         
             
                  return from(left).merge(right)
         
     | 
| 
       123 
453 
     | 
    
         
             
                end
         
     | 
| 
       124 
454 
     | 
    
         | 
| 
      
 455 
     | 
    
         
            +
                # Merges object into current map.
         
     | 
| 
      
 456 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, String, JOSE::JWS] object
         
     | 
| 
      
 457 
     | 
    
         
            +
                # @return [JOSE::JWS]
         
     | 
| 
       125 
458 
     | 
    
         
             
                def merge(object)
         
     | 
| 
       126 
459 
     | 
    
         
             
                  object = case object
         
     | 
| 
       127 
460 
     | 
    
         
             
                  when JOSE::Map, Hash
         
     | 
| 
         @@ -136,6 +469,14 @@ module JOSE 
     | 
|
| 
       136 
469 
     | 
    
         
             
                  return JOSE::JWS.from_map(self.to_map.merge(object))
         
     | 
| 
       137 
470 
     | 
    
         
             
                end
         
     | 
| 
       138 
471 
     | 
    
         | 
| 
      
 472 
     | 
    
         
            +
                # Returns the decoded payload portion of a signed binary or map without verifying the signature.
         
     | 
| 
      
 473 
     | 
    
         
            +
                #
         
     | 
| 
      
 474 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 475 
     | 
    
         
            +
                #     JOSE::JWS.peek_payload("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.dMAojPMVbFvvkouYUSI9AxIRBxgqretQMCvNF7KmTHU")
         
     | 
| 
      
 476 
     | 
    
         
            +
                #     # => "{}"
         
     | 
| 
      
 477 
     | 
    
         
            +
                #
         
     | 
| 
      
 478 
     | 
    
         
            +
                # @param [JOSE::SignedBinary, String] signed
         
     | 
| 
      
 479 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
       139 
480 
     | 
    
         
             
                def self.peek_payload(signed)
         
     | 
| 
       140 
481 
     | 
    
         
             
                  if signed.is_a?(String)
         
     | 
| 
       141 
482 
     | 
    
         
             
                    signed = expand(signed)
         
     | 
| 
         @@ -143,6 +484,14 @@ module JOSE 
     | 
|
| 
       143 
484 
     | 
    
         
             
                  return JOSE.urlsafe_decode64(signed['payload'])
         
     | 
| 
       144 
485 
     | 
    
         
             
                end
         
     | 
| 
       145 
486 
     | 
    
         | 
| 
      
 487 
     | 
    
         
            +
                # Returns the decoded protected portion of a signed binary or map without verifying the signature.
         
     | 
| 
      
 488 
     | 
    
         
            +
                #
         
     | 
| 
      
 489 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 490 
     | 
    
         
            +
                #     JOSE::JWS.peek_protected("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.dMAojPMVbFvvkouYUSI9AxIRBxgqretQMCvNF7KmTHU")
         
     | 
| 
      
 491 
     | 
    
         
            +
                #     # => JOSE::Map["alg" => "HS256", "typ" => "JWT"]
         
     | 
| 
      
 492 
     | 
    
         
            +
                #
         
     | 
| 
      
 493 
     | 
    
         
            +
                # @param [JOSE::SignedBinary, String] signed
         
     | 
| 
      
 494 
     | 
    
         
            +
                # @return [JOSE::Map]
         
     | 
| 
       146 
495 
     | 
    
         
             
                def self.peek_protected(signed)
         
     | 
| 
       147 
496 
     | 
    
         
             
                  if signed.is_a?(String)
         
     | 
| 
       148 
497 
     | 
    
         
             
                    signed = expand(signed)
         
     | 
| 
         @@ -150,27 +499,112 @@ module JOSE 
     | 
|
| 
       150 
499 
     | 
    
         
             
                  return JOSE::Map.new(JOSE.decode(JOSE.urlsafe_decode64(signed['protected'])))
         
     | 
| 
       151 
500 
     | 
    
         
             
                end
         
     | 
| 
       152 
501 
     | 
    
         | 
| 
       153 
     | 
    
         
            -
                 
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
      
 502 
     | 
    
         
            +
                # Returns the decoded signature portion of a signed binary or map without verifying the signature.
         
     | 
| 
      
 503 
     | 
    
         
            +
                #
         
     | 
| 
      
 504 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 505 
     | 
    
         
            +
                #     JOSE::JWS.peek_signature("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.dMAojPMVbFvvkouYUSI9AxIRBxgqretQMCvNF7KmTHU")
         
     | 
| 
      
 506 
     | 
    
         
            +
                #     # => "t\xC0(\x8C\xF3\x15l[\xEF\x92\x8B\x98Q\"=\x03\x12\x11\a\x18*\xAD\xEBP0+\xCD\x17\xB2\xA6Lu"
         
     | 
| 
      
 507 
     | 
    
         
            +
                #
         
     | 
| 
      
 508 
     | 
    
         
            +
                # @param [JOSE::SignedBinary, String] signed
         
     | 
| 
      
 509 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 510 
     | 
    
         
            +
                def self.peek_signature(signed)
         
     | 
| 
      
 511 
     | 
    
         
            +
                  if signed.is_a?(String)
         
     | 
| 
      
 512 
     | 
    
         
            +
                    signed = expand(signed)
         
     | 
| 
      
 513 
     | 
    
         
            +
                  end
         
     | 
| 
      
 514 
     | 
    
         
            +
                  return JOSE.urlsafe_decode64(signed['signature'])
         
     | 
| 
      
 515 
     | 
    
         
            +
                end
         
     | 
| 
      
 516 
     | 
    
         
            +
             
     | 
| 
      
 517 
     | 
    
         
            +
                # Signs the `plain_text` using the `jwk` and algorithm specified by the `jws`.
         
     | 
| 
      
 518 
     | 
    
         
            +
                #
         
     | 
| 
      
 519 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 520 
     | 
    
         
            +
                #     jwk = JOSE::JWK.from({"k" => "qUg4Yw", "kty" => "oct"})
         
     | 
| 
      
 521 
     | 
    
         
            +
                #     # => #<struct JOSE::JWK keys=nil, kty=#<struct JOSE::JWK::KTY_oct oct="\xA9H8c">, fields=JOSE::Map[]>
         
     | 
| 
      
 522 
     | 
    
         
            +
                #     JOSE::JWS.sign(jwk, "{}", { "alg" => "HS256" })
         
     | 
| 
      
 523 
     | 
    
         
            +
                #     # => JOSE::SignedMap[
         
     | 
| 
      
 524 
     | 
    
         
            +
                #     #  "signature" => "5paAJxaOXSqRUIXrP_vJXUZu2SCBH-ojgP4D6Xr6GPU",
         
     | 
| 
      
 525 
     | 
    
         
            +
                #     #  "protected" => "eyJhbGciOiJIUzI1NiJ9",
         
     | 
| 
      
 526 
     | 
    
         
            +
                #     #  "payload" => "e30"]
         
     | 
| 
      
 527 
     | 
    
         
            +
                #
         
     | 
| 
      
 528 
     | 
    
         
            +
                # If the `jwk` has a `"kid"` assigned, it will be added to the `"header"` on the signed map:
         
     | 
| 
      
 529 
     | 
    
         
            +
                #
         
     | 
| 
      
 530 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 531 
     | 
    
         
            +
                #     jwk = JOSE::JWK.from({"k" => "qUg4Yw", "kid" => "eyHC48MN26DvoBpkaudvOVXuI5Sy8fKMxQMYiRWmjFw", "kty" => "oct"})
         
     | 
| 
      
 532 
     | 
    
         
            +
                #     # => #<struct JOSE::JWK
         
     | 
| 
      
 533 
     | 
    
         
            +
                #     #  keys=nil,
         
     | 
| 
      
 534 
     | 
    
         
            +
                #     #  kty=#<struct JOSE::JWK::KTY_oct oct="\xA9H8c">,
         
     | 
| 
      
 535 
     | 
    
         
            +
                #     #  fields=JOSE::Map["kid" => "eyHC48MN26DvoBpkaudvOVXuI5Sy8fKMxQMYiRWmjFw"]>
         
     | 
| 
      
 536 
     | 
    
         
            +
                #     JOSE::JWS.sign(jwk, "test", { "alg" => "HS256" })
         
     | 
| 
      
 537 
     | 
    
         
            +
                #     # => JOSE::SignedMap[
         
     | 
| 
      
 538 
     | 
    
         
            +
                #     #  "signature" => "ZEBxtZ4SAW5hYyT7CKxH8dqynTAg-Y24QjkudQMaA_M",
         
     | 
| 
      
 539 
     | 
    
         
            +
                #     #  "header" => {"kid"=>"eyHC48MN26DvoBpkaudvOVXuI5Sy8fKMxQMYiRWmjFw"},
         
     | 
| 
      
 540 
     | 
    
         
            +
                #     #  "protected" => "eyJhbGciOiJIUzI1NiJ9",
         
     | 
| 
      
 541 
     | 
    
         
            +
                #     #  "payload" => "dGVzdA"]
         
     | 
| 
      
 542 
     | 
    
         
            +
                #
         
     | 
| 
      
 543 
     | 
    
         
            +
                # *Note:* Signed maps with a `"header"` or other fields will have data loss when used with {JOSE::JWS.compact JOSE::JWS.compact}.
         
     | 
| 
      
 544 
     | 
    
         
            +
                # @param [JOSE::JWK] jwk
         
     | 
| 
      
 545 
     | 
    
         
            +
                # @param [String] plain_text
         
     | 
| 
      
 546 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, String, JOSE::JWS] jws
         
     | 
| 
      
 547 
     | 
    
         
            +
                # @param [JOSE::Map, Hash] header
         
     | 
| 
      
 548 
     | 
    
         
            +
                # @return [JOSE::SignedMap]
         
     | 
| 
      
 549 
     | 
    
         
            +
                def self.sign(jwk, plain_text, jws, header = nil)
         
     | 
| 
      
 550 
     | 
    
         
            +
                  return from(jws).sign(jwk, plain_text, header)
         
     | 
| 
       155 
551 
     | 
    
         
             
                end
         
     | 
| 
       156 
552 
     | 
    
         | 
| 
       157 
     | 
    
         
            -
                 
     | 
| 
      
 553 
     | 
    
         
            +
                # Signs the `plain_text` using the `jwk` and algorithm specified by the `jws`.
         
     | 
| 
      
 554 
     | 
    
         
            +
                # @see JOSE::JWS.sign
         
     | 
| 
      
 555 
     | 
    
         
            +
                # @param [JOSE::JWK] jwk
         
     | 
| 
      
 556 
     | 
    
         
            +
                # @param [String] plain_text
         
     | 
| 
      
 557 
     | 
    
         
            +
                # @param [JOSE::Map, Hash] header
         
     | 
| 
      
 558 
     | 
    
         
            +
                # @return [JOSE::SignedMap]
         
     | 
| 
      
 559 
     | 
    
         
            +
                def sign(jwk, plain_text, header = nil)
         
     | 
| 
       158 
560 
     | 
    
         
             
                  protected_binary = JOSE.urlsafe_encode64(to_binary)
         
     | 
| 
       159 
561 
     | 
    
         
             
                  payload = JOSE.urlsafe_encode64(plain_text)
         
     | 
| 
       160 
562 
     | 
    
         
             
                  signing_input = signing_input(plain_text, protected_binary)
         
     | 
| 
       161 
     | 
    
         
            -
                  signature = JOSE.urlsafe_encode64(alg.sign( 
     | 
| 
       162 
     | 
    
         
            -
                  return signature_to_map(payload, protected_binary, header,  
     | 
| 
      
 563 
     | 
    
         
            +
                  signature = JOSE.urlsafe_encode64(alg.sign(jwk, signing_input))
         
     | 
| 
      
 564 
     | 
    
         
            +
                  return signature_to_map(payload, protected_binary, header, jwk, signature)
         
     | 
| 
      
 565 
     | 
    
         
            +
                end
         
     | 
| 
      
 566 
     | 
    
         
            +
             
     | 
| 
      
 567 
     | 
    
         
            +
                # Combines `payload` and `protected_binary` based on the `"b64"` setting on the `jws` for the signing input used by {JOSE::JWS.sign JOSE::JWS.sign}.
         
     | 
| 
      
 568 
     | 
    
         
            +
                #
         
     | 
| 
      
 569 
     | 
    
         
            +
                # If `"b64"` is set to `false` on the `jws`, the raw `payload` will be used:
         
     | 
| 
      
 570 
     | 
    
         
            +
                #
         
     | 
| 
      
 571 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 572 
     | 
    
         
            +
                #     JOSE::JWS.signing_input("{}", { "alg" => "HS256" })
         
     | 
| 
      
 573 
     | 
    
         
            +
                #     # => "eyJhbGciOiJIUzI1NiJ9.e30"
         
     | 
| 
      
 574 
     | 
    
         
            +
                #     JOSE::JWS.signing_input("{}", { "alg" => "HS256", "b64" => false })
         
     | 
| 
      
 575 
     | 
    
         
            +
                #     # => "eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2V9.{}"
         
     | 
| 
      
 576 
     | 
    
         
            +
                #
         
     | 
| 
      
 577 
     | 
    
         
            +
                # @see https://tools.ietf.org/html/draft-ietf-jose-jws-signing-input-options-04 JWS Unencoded Payload Option
         
     | 
| 
      
 578 
     | 
    
         
            +
                # @param [String] payload
         
     | 
| 
      
 579 
     | 
    
         
            +
                # @param [JOSE::Map, Hash, String, JOSE::JWS] jws
         
     | 
| 
      
 580 
     | 
    
         
            +
                # @param [String] protected_binary
         
     | 
| 
      
 581 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 582 
     | 
    
         
            +
                def self.signing_input(payload, jws, protected_binary = nil)
         
     | 
| 
      
 583 
     | 
    
         
            +
                  return from(jws).signing_input(payload, protected_binary)
         
     | 
| 
       163 
584 
     | 
    
         
             
                end
         
     | 
| 
       164 
585 
     | 
    
         | 
| 
       165 
     | 
    
         
            -
                #  
     | 
| 
       166 
     | 
    
         
            -
                 
     | 
| 
      
 586 
     | 
    
         
            +
                # Combines `payload` and `protected_binary` based on the `"b64"` setting on the `jws` for the signing input used by {JOSE::JWS.sign JOSE::JWS.sign}.
         
     | 
| 
      
 587 
     | 
    
         
            +
                # @see JOSE::JWS.signing_input
         
     | 
| 
      
 588 
     | 
    
         
            +
                def signing_input(payload, protected_binary = nil)
         
     | 
| 
       167 
589 
     | 
    
         
             
                  if b64 == true or b64.nil?
         
     | 
| 
       168 
590 
     | 
    
         
             
                    payload = JOSE.urlsafe_encode64(payload)
         
     | 
| 
       169 
591 
     | 
    
         
             
                  end
         
     | 
| 
      
 592 
     | 
    
         
            +
                  protected_binary ||= JOSE.urlsafe_encode64(to_binary)
         
     | 
| 
       170 
593 
     | 
    
         
             
                  return [protected_binary, '.', payload].join
         
     | 
| 
       171 
594 
     | 
    
         
             
                end
         
     | 
| 
       172 
595 
     | 
    
         | 
| 
       173 
     | 
    
         
            -
                 
     | 
| 
      
 596 
     | 
    
         
            +
                # Verifies the `signed` using the `jwk`.
         
     | 
| 
      
 597 
     | 
    
         
            +
                #
         
     | 
| 
      
 598 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 599 
     | 
    
         
            +
                #     jwk = JOSE::JWK.from({"k" => "qUg4Yw", "kty" => "oct"})
         
     | 
| 
      
 600 
     | 
    
         
            +
                #     # => #<struct JOSE::JWK keys=nil, kty=#<struct JOSE::JWK::KTY_oct oct="\xA9H8c">, fields=JOSE::Map[]>
         
     | 
| 
      
 601 
     | 
    
         
            +
                #     JOSE::JWS.verify(jwk, "eyJhbGciOiJIUzI1NiJ9.e30.5paAJxaOXSqRUIXrP_vJXUZu2SCBH-ojgP4D6Xr6GPU")
         
     | 
| 
      
 602 
     | 
    
         
            +
                #     # => => [true, "{}", #<struct JOSE::JWS alg=#<struct JOSE::JWS::ALG_HMAC hmac=OpenSSL::Digest::SHA256>, b64=nil, fields=JOSE::Map[]>]
         
     | 
| 
      
 603 
     | 
    
         
            +
                #
         
     | 
| 
      
 604 
     | 
    
         
            +
                # @param [JOSE::JWK] jwk
         
     | 
| 
      
 605 
     | 
    
         
            +
                # @param [JOSE::SignedBinary, JOSE::SignedMap, Hash, String] signed
         
     | 
| 
      
 606 
     | 
    
         
            +
                # @return [[Boolean, String, JOSE::JWS]]
         
     | 
| 
      
 607 
     | 
    
         
            +
                def self.verify(jwk, signed)
         
     | 
| 
       174 
608 
     | 
    
         
             
                  if signed.is_a?(String)
         
     | 
| 
       175 
609 
     | 
    
         
             
                    signed = JOSE::JWS.expand(signed)
         
     | 
| 
       176 
610 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -181,18 +615,49 @@ module JOSE 
     | 
|
| 
       181 
615 
     | 
    
         
             
                    jws = from_binary(JOSE.urlsafe_decode64(signed['protected']))
         
     | 
| 
       182 
616 
     | 
    
         
             
                    signature = JOSE.urlsafe_decode64(signed['signature'])
         
     | 
| 
       183 
617 
     | 
    
         
             
                    plain_text = JOSE.urlsafe_decode64(signed['payload'])
         
     | 
| 
       184 
     | 
    
         
            -
                    return jws.verify( 
     | 
| 
      
 618 
     | 
    
         
            +
                    return jws.verify(jwk, plain_text, signature, signed['protected'])
         
     | 
| 
       185 
619 
     | 
    
         
             
                  else
         
     | 
| 
       186 
620 
     | 
    
         
             
                    raise ArgumentError, "'signed' is not a valid signed String, Hash, or JOSE::Map"
         
     | 
| 
       187 
621 
     | 
    
         
             
                  end
         
     | 
| 
       188 
622 
     | 
    
         
             
                end
         
     | 
| 
       189 
623 
     | 
    
         | 
| 
       190 
     | 
    
         
            -
                 
     | 
| 
      
 624 
     | 
    
         
            +
                # Verifies the `signature` using the `jwk`, `plain_text`, and `protected_binary`.
         
     | 
| 
      
 625 
     | 
    
         
            +
                # @see JOSE::JWS.verify
         
     | 
| 
      
 626 
     | 
    
         
            +
                # @see JOSE::JWS.verify_strict
         
     | 
| 
      
 627 
     | 
    
         
            +
                # @param [JOSE::JWK] jwk
         
     | 
| 
      
 628 
     | 
    
         
            +
                # @param [String] plain_text
         
     | 
| 
      
 629 
     | 
    
         
            +
                # @param [String] signature
         
     | 
| 
      
 630 
     | 
    
         
            +
                # @param [String] protected_binary
         
     | 
| 
      
 631 
     | 
    
         
            +
                # @return [[Boolean, String, JOSE::JWS]]
         
     | 
| 
      
 632 
     | 
    
         
            +
                def verify(jwk, plain_text, signature, protected_binary = nil)
         
     | 
| 
      
 633 
     | 
    
         
            +
                  protected_binary ||= JOSE.urlsafe_encode64(to_binary)
         
     | 
| 
       191 
634 
     | 
    
         
             
                  signing_input = signing_input(plain_text, protected_binary)
         
     | 
| 
       192 
     | 
    
         
            -
                  return alg.verify( 
     | 
| 
      
 635 
     | 
    
         
            +
                  return alg.verify(jwk, signing_input, signature), plain_text, self
         
     | 
| 
       193 
636 
     | 
    
         
             
                end
         
     | 
| 
       194 
637 
     | 
    
         | 
| 
       195 
     | 
    
         
            -
                 
     | 
| 
      
 638 
     | 
    
         
            +
                # Same as {JOSE::JWS.verify JOSE::JWS.verify}, but uses `allow` as a whitelist for `"alg"` which are allowed to verify against.
         
     | 
| 
      
 639 
     | 
    
         
            +
                #
         
     | 
| 
      
 640 
     | 
    
         
            +
                # If the detected algorithm is not present in `allow`, then `false` is returned.
         
     | 
| 
      
 641 
     | 
    
         
            +
                #
         
     | 
| 
      
 642 
     | 
    
         
            +
                #     !!!ruby
         
     | 
| 
      
 643 
     | 
    
         
            +
                #     jwk = JOSE::JWK.from({"k" => "qUg4Yw", "kty" => "oct"})
         
     | 
| 
      
 644 
     | 
    
         
            +
                #     # => #<struct JOSE::JWK keys=nil, kty=#<struct JOSE::JWK::KTY_oct oct="\xA9H8c">, fields=JOSE::Map[]>
         
     | 
| 
      
 645 
     | 
    
         
            +
                #     signed_hs256 = JOSE::JWS.sign(jwk, "{}", { "alg" => "HS256" }).compact
         
     | 
| 
      
 646 
     | 
    
         
            +
                #     # => "eyJhbGciOiJIUzI1NiJ9.e30.5paAJxaOXSqRUIXrP_vJXUZu2SCBH-ojgP4D6Xr6GPU"
         
     | 
| 
      
 647 
     | 
    
         
            +
                #     signed_hs512 = JOSE::JWS.sign(jwk, "{}", { "alg" => "HS512" }).compact
         
     | 
| 
      
 648 
     | 
    
         
            +
                #     # => "eyJhbGciOiJIUzUxMiJ9.e30.DN_JCks5rzQiDJJ15E6uJFskAMw-KcasGINKK_4S8xKo7W6tZ-a00ZL8UWOWgE7oHpcFrYnvSpNRldAMp19iyw"
         
     | 
| 
      
 649 
     | 
    
         
            +
                #     JOSE::JWS.verify_strict(jwk, ["HS256"], signed_hs256).first
         
     | 
| 
      
 650 
     | 
    
         
            +
                #     # => true
         
     | 
| 
      
 651 
     | 
    
         
            +
                #     JOSE::JWS.verify_strict(jwk, ["HS256"], signed_hs512).first
         
     | 
| 
      
 652 
     | 
    
         
            +
                #     # => false
         
     | 
| 
      
 653 
     | 
    
         
            +
                #     JOSE::JWS.verify_strict(jwk, ["HS256", "HS512"], signed_hs512).first
         
     | 
| 
      
 654 
     | 
    
         
            +
                #     # => true
         
     | 
| 
      
 655 
     | 
    
         
            +
                #
         
     | 
| 
      
 656 
     | 
    
         
            +
                # @param [JOSE::JWK] jwk
         
     | 
| 
      
 657 
     | 
    
         
            +
                # @param [Array<String>] allow
         
     | 
| 
      
 658 
     | 
    
         
            +
                # @param [JOSE::SignedBinary, JOSE::SignedMap, Hash, String] signed
         
     | 
| 
      
 659 
     | 
    
         
            +
                # @return [[Boolean, String, (JOSE::JWS, JOSE::Map)]]
         
     | 
| 
      
 660 
     | 
    
         
            +
                def self.verify_strict(jwk, allow, signed)
         
     | 
| 
       196 
661 
     | 
    
         
             
                  if signed.is_a?(String)
         
     | 
| 
       197 
662 
     | 
    
         
             
                    signed = JOSE::JWS.expand(signed)
         
     | 
| 
       198 
663 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -205,7 +670,7 @@ module JOSE 
     | 
|
| 
       205 
670 
     | 
    
         
             
                    if allow.member?(protected_map['alg'])
         
     | 
| 
       206 
671 
     | 
    
         
             
                      jws = from_map(protected_map)
         
     | 
| 
       207 
672 
     | 
    
         
             
                      signature = JOSE.urlsafe_decode64(signed['signature'])
         
     | 
| 
       208 
     | 
    
         
            -
                      return jws.verify( 
     | 
| 
      
 673 
     | 
    
         
            +
                      return jws.verify(jwk, plain_text, signature, signed['protected'])
         
     | 
| 
       209 
674 
     | 
    
         
             
                    else
         
     | 
| 
       210 
675 
     | 
    
         
             
                      return false, plain_text, protected_map
         
     | 
| 
       211 
676 
     | 
    
         
             
                    end
         
     |