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,84 @@ 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' )
4546
46- cek = Alg . decrypt_cek ( header [ 'alg' ] , key , enc_key )
47- cipher = Enc . for ( header [ 'enc' ] , cek , iv , tag )
47+ Validator . new . check_params ( alg , enc , zip , key )
48+
49+ cek = Alg . decrypt_cek ( alg , key , enc_key )
50+ cipher = Enc . for ( enc , cek , iv , tag )
4851
4952 plaintext = cipher . decrypt ( ciphertext , payload . split ( '.' ) . first )
5053
51- apply_zip ( header , plaintext , :decompress )
54+ return plaintext unless zip
55+
56+ Zip . for ( zip ) . new . decompress ( plaintext )
5257 end
5358
59+ # @deprecated Use Validator.new.check_params instead
5460 def check_params ( header , key )
61+ warn '[DEPRECATION] `JWE.check_params` is deprecated. Use `JWE::Validator.new.check_params` instead.'
5562 check_alg ( header [ :alg ] || header [ 'alg' ] )
5663 check_enc ( header [ :enc ] || header [ 'enc' ] )
5764 check_zip ( header [ :zip ] || header [ 'zip' ] )
5865 check_key ( key )
5966 end
6067
68+ # @deprecated Use Validator.new.check_params instead
6169 def check_alg ( alg )
62- raise ArgumentError . new ( "\" #{ alg } \" is not a valid alg method" ) unless VALID_ALG . include? ( alg )
70+ warn '[DEPRECATION] `JWE.check_alg` is deprecated. Please validate parameters manually.'
71+ raise ArgumentError . new ( "\" #{ alg } \" is not a valid alg method" ) unless Validator ::VALID_ALG . include? ( alg )
6372 end
6473
74+ # @deprecated Use Validator.new.check_params instead
6575 def check_enc ( enc )
66- raise ArgumentError . new ( "\" #{ enc } \" is not a valid enc method" ) unless VALID_ENC . include? ( enc )
76+ warn '[DEPRECATION] `JWE.check_enc` is deprecated. Please validate parameters manually.'
77+ raise ArgumentError . new ( "\" #{ enc } \" is not a valid enc method" ) unless Validator ::VALID_ENC . include? ( enc )
6778 end
6879
80+ # @deprecated Use Validator.new.check_params instead
6981 def check_zip ( zip )
70- raise ArgumentError . new ( "\" #{ zip } \" is not a valid zip method" ) unless zip . nil? || zip == '' || VALID_ZIP . include? ( zip )
82+ warn '[DEPRECATION] `JWE.check_zip` is deprecated. Please validate parameters manually.'
83+ raise ArgumentError . new ( "\" #{ zip } \" is not a valid zip method" ) unless zip . nil? || zip == '' || Validator ::VALID_ZIP . include? ( zip )
7184 end
7285
86+ # @deprecated Use Validator.new.check_params instead
7387 def check_key ( key )
88+ warn '[DEPRECATION] `JWE.check_key` is deprecated. Please validate parameters manually.'
7489 raise ArgumentError . new ( 'The key must not be nil or blank' ) if key . nil? || ( key . is_a? ( String ) && key . strip == '' )
7590 end
7691
92+ # @deprecated Use NameResolver#param_to_class_name instead
7793 def param_to_class_name ( param )
94+ warn '[DEPRECATION] `JWE.param_to_class_name` is deprecated. Use `JWE::NameResolver#param_to_class_name` instead.'
7895 klass = param . gsub ( /[-+]/ , '_' ) . downcase . sub ( /^[a-z\d ]*/ ) { ::Regexp . last_match ( 0 ) . capitalize }
7996 klass . gsub ( /_([a-z\d ]*)/i ) { Regexp . last_match ( 1 ) . capitalize }
8097 end
8198
99+ # @deprecated Internal method, do not use
82100 def apply_zip ( header , data , direction )
101+ warn '[DEPRECATION] `JWE.apply_zip` is deprecated. This is an internal method and should not be used externally.'
83102 zip = header [ :zip ] || header [ 'zip' ]
84103 if zip
85104 Zip . for ( zip ) . new . send ( direction , data )
@@ -88,13 +107,17 @@ def apply_zip(header, data, direction)
88107 end
89108 end
90109
110+ # @deprecated Use Header.new.generate_header instead
91111 def generate_header ( alg , enc , more )
112+ warn '[DEPRECATION] `JWE.generate_header` is deprecated. This is an internal method and should not be used externally.'
92113 header = { alg : alg , enc : enc } . merge ( more )
93114 header . delete ( :zip ) if header [ :zip ] == ''
94115 header
95116 end
96117
118+ # @deprecated Use Serialization::Compact.encode instead
97119 def generate_serialization ( hdr , cek , content , cipher )
120+ warn '[DEPRECATION] `JWE.generate_serialization` is deprecated. Use `JWE::Serialization::Compact.encode` instead.'
98121 Serialization ::Compact . encode ( hdr , cek , cipher . iv , content , cipher . tag )
99122 end
100123 end
0 commit comments