77
88require  'jwe/base64' 
99require  'jwe/serialization/compact' 
10+ require  'jwe/name_resolver' 
1011require  'jwe/alg' 
1112require  'jwe/enc' 
1213require  'jwe/zip' 
14+ require  'jwe/validator' 
15+ require  'jwe/header' 
1316
1417# A ruby implementation of the RFC 7516 JSON Web Encryption (JWE) standard. 
1518module  JWE 
@@ -18,68 +21,90 @@ class NotImplementedError < RuntimeError; end
1821  class  BadCEK  < RuntimeError ;  end 
1922  class  InvalidData  < RuntimeError ;  end 
2023
21-   VALID_ALG  =  [ 'RSA1_5' ,  'RSA-OAEP' ,  'RSA-OAEP-256' ,  'A128KW' ,  'A192KW' ,  'A256KW' ,  'dir' ,  'ECDH-ES' ,  'ECDH-ES+A128KW' ,  'ECDH-ES+A192KW' ,  'ECDH-ES+A256KW' ,  'A128GCMKW' ,  'A192GCMKW' ,  'A256GCMKW' ,  'PBES2-HS256+A128KW' ,  'PBES2-HS384+A192KW' ,  'PBES2-HS512+A256KW' ] . freeze 
22-   VALID_ENC  =  %w[ A128CBC-HS256  A192CBC-HS384  A256CBC-HS512  A128GCM  A192GCM  A256GCM ] . freeze 
23-   VALID_ZIP  =  [ 'DEF' ] . freeze 
24- 
2524  class  << self 
26-     def  encrypt ( payload ,  key ,  alg : 'RSA-OAEP' ,  enc : 'A128GCM' ,  **more_headers ) 
27-       header  =  generate_header ( alg ,  enc ,  more_headers ) 
28-       check_params ( header ,  key ) 
25+     def  encrypt ( payload ,  key ,  alg : 'RSA-OAEP' ,  enc : 'A128GCM' ,  zip : nil ,  **more_headers ) 
26+       Validator . new . check_params ( alg ,  enc ,  zip ,  key ) 
27+       payload  =  Zip . for ( zip ) . new . compress ( payload )  if  zip 
28+ 
29+       enc_cipher  =  Enc . for ( enc ) 
30+       enc_cipher . cek  =  key  if  alg  == 'dir' 
2931
30-       payload  =  apply_zip ( header ,  payload ,  :compress ) 
32+       alg_cipher  =  Alg . for ( alg ) . new ( key ) 
33+       encrypted_cek  =  alg_cipher . encrypt ( enc_cipher . cek ) 
3134
32-       cipher  =  Enc . for ( enc ) 
33-       cipher . cek  =  key  if  alg  == 'dir' 
35+       header  =  Header . new . generate_header ( alg_cipher ,  enc_cipher ,  zip ,  more_headers ) 
3436
35-       json_hdr  =  header . to_json 
36-       ciphertext  =  cipher . encrypt ( payload ,  Base64 . jwe_encode ( json_hdr ) ) 
37+       ciphertext  =  enc_cipher . encrypt ( payload ,  Base64 . jwe_encode ( header ) ) 
3738
38-       generate_serialization ( json_hdr ,   Alg . encrypt_cek ( alg ,   key ,   cipher . cek ) ,  ciphertext ,  cipher ) 
39+       Serialization :: Compact . encode ( header ,   encrypted_cek ,   enc_cipher . iv ,  ciphertext ,  enc_cipher . tag ) 
3940    end 
4041
4142    def  decrypt ( payload ,  key ) 
4243      header ,  enc_key ,  iv ,  ciphertext ,  tag  =  Serialization ::Compact . decode ( payload ) 
4344      header  =  JSON . parse ( header ) 
44-       check_params ( header ,  key ) 
45+       alg ,  enc ,  zip  =  header . values_at ( 'alg' ,  'enc' ,  'zip' ) 
46+ 
47+       Validator . new . check_params ( alg ,  enc ,  zip ,  key ) 
48+ 
49+       alg_cipher  =  Alg . for ( alg ) . new ( key ) 
50+       if  alg_cipher . need_additional_header_parameters? 
51+         alg_cipher . iv  =  Base64 . jwe_decode ( header [ 'iv' ] ) 
52+         alg_cipher . tag  =  Base64 . jwe_decode ( header [ 'tag' ] ) 
53+       end 
54+ 
55+       cek  =  alg_cipher . decrypt ( enc_key ) 
56+       enc_cipher  =  Enc . for ( enc ,  cek ,  iv ,  tag ) 
4557
46-       cek  =  Alg . decrypt_cek ( header [ 'alg' ] ,  key ,  enc_key ) 
47-       cipher  =  Enc . for ( header [ 'enc' ] ,  cek ,  iv ,  tag ) 
58+       plaintext  =  enc_cipher . decrypt ( ciphertext ,  payload . split ( '.' ) . first ) 
4859
49-       plaintext  =   cipher . decrypt ( ciphertext ,   payload . split ( '.' ) . first ) 
60+       return   plaintext  unless   zip 
5061
51-       apply_zip ( header ,   plaintext ,   : decompress) 
62+       Zip . for ( zip ) . new . decompress ( plaintext ) 
5263    end 
5364
65+     # @deprecated Use Validator.new.check_params instead 
5466    def  check_params ( header ,  key ) 
67+       warn  '[DEPRECATION] `JWE.check_params` is deprecated. Use `JWE::Validator.new.check_params` instead.' 
5568      check_alg ( header [ :alg ]  || header [ 'alg' ] ) 
5669      check_enc ( header [ :enc ]  || header [ 'enc' ] ) 
5770      check_zip ( header [ :zip ]  || header [ 'zip' ] ) 
5871      check_key ( key ) 
5972    end 
6073
74+     # @deprecated Use Validator.new.check_params instead 
6175    def  check_alg ( alg ) 
62-       raise  ArgumentError . new ( "\" #{ alg } \"  is not a valid alg method" )  unless  VALID_ALG . include? ( alg ) 
76+       warn  '[DEPRECATION] `JWE.check_alg` is deprecated. Please validate parameters manually.' 
77+       raise  ArgumentError . new ( "\" #{ alg } \"  is not a valid alg method" )  unless  Validator ::VALID_ALG . include? ( alg ) 
6378    end 
6479
80+     # @deprecated Use Validator.new.check_params instead 
6581    def  check_enc ( enc ) 
66-       raise  ArgumentError . new ( "\" #{ enc } \"  is not a valid enc method" )  unless  VALID_ENC . include? ( enc ) 
82+       warn  '[DEPRECATION] `JWE.check_enc` is deprecated. Please validate parameters manually.' 
83+       raise  ArgumentError . new ( "\" #{ enc } \"  is not a valid enc method" )  unless  Validator ::VALID_ENC . include? ( enc ) 
6784    end 
6885
86+     # @deprecated Use Validator.new.check_params instead 
6987    def  check_zip ( zip ) 
70-       raise  ArgumentError . new ( "\" #{ zip } \"  is not a valid zip method" )  unless  zip . nil?  || zip  == ''  || VALID_ZIP . include? ( zip ) 
88+       warn  '[DEPRECATION] `JWE.check_zip` is deprecated. Please validate parameters manually.' 
89+       raise  ArgumentError . new ( "\" #{ zip } \"  is not a valid zip method" )  unless  zip . nil?  || zip  == ''  || Validator ::VALID_ZIP . include? ( zip ) 
7190    end 
7291
92+     # @deprecated Use Validator.new.check_params instead 
7393    def  check_key ( key ) 
94+       warn  '[DEPRECATION] `JWE.check_key` is deprecated. Please validate parameters manually.' 
7495      raise  ArgumentError . new ( 'The key must not be nil or blank' )  if  key . nil?  || ( key . is_a? ( String )  && key . strip  == '' ) 
7596    end 
7697
98+     # @deprecated Use NameResolver#param_to_class_name instead 
7799    def  param_to_class_name ( param ) 
100+       warn  '[DEPRECATION] `JWE.param_to_class_name` is deprecated. Use `JWE::NameResolver#param_to_class_name` instead.' 
78101      klass  =  param . gsub ( /[-+]/ ,  '_' ) . downcase . sub ( /^[a-z\d ]*/ )  {  ::Regexp . last_match ( 0 ) . capitalize  } 
79102      klass . gsub ( /_([a-z\d ]*)/i )  {  Regexp . last_match ( 1 ) . capitalize  } 
80103    end 
81104
105+     # @deprecated Internal method, do not use 
82106    def  apply_zip ( header ,  data ,  direction ) 
107+       warn  '[DEPRECATION] `JWE.apply_zip` is deprecated. This is an internal method and should not be used externally.' 
83108      zip  =  header [ :zip ]  || header [ 'zip' ] 
84109      if  zip 
85110        Zip . for ( zip ) . new . send ( direction ,  data ) 
@@ -88,13 +113,17 @@ def apply_zip(header, data, direction)
88113      end 
89114    end 
90115
116+     # @deprecated Use Header.new.generate_header instead 
91117    def  generate_header ( alg ,  enc ,  more ) 
118+       warn  '[DEPRECATION] `JWE.generate_header` is deprecated. This is an internal method and should not be used externally.' 
92119      header  =  {  alg : alg ,  enc : enc  } . merge ( more ) 
93120      header . delete ( :zip )  if  header [ :zip ]  == '' 
94121      header 
95122    end 
96123
124+     # @deprecated Use Serialization::Compact.encode instead 
97125    def  generate_serialization ( hdr ,  cek ,  content ,  cipher ) 
126+       warn  '[DEPRECATION] `JWE.generate_serialization` is deprecated. Use `JWE::Serialization::Compact.encode` instead.' 
98127      Serialization ::Compact . encode ( hdr ,  cek ,  cipher . iv ,  content ,  cipher . tag ) 
99128    end 
100129  end 
0 commit comments